1 /******************************************************************************
2 *
3 *  NSSDC/CDF                                         CDFedit, part 0 (main).
4 *
5 *  Version 1.3b, 16-Nov-97, Hughes STX.
6 *
7 *  Modification history:
8 *
9 *   V1.0  25-Jan-94, J Love     Original version.
10 *   V1.0a  4-Feb-94, J Love     DEC Alpha/OpenVMS port.
11 *   V1.1  15-Dec-94, J Love     CDF V2.5.
12 *   V1.1a 10-Jan-95, J Love	Uppercase file extensions on the Macintosh.
13 *   V1.1b 23-Jan-95, J Love	IRIX 6.x (64-bit).
14 *   V1.1c 28-Feb-95, J Love	Pass `char' as `int'.
15 *   V1.2  11-Apr-95, J Love	POSIX.
16 *   V1.2a 18-Apr-95, J Love	More POSIX.
17 *   V1.2b  6-Sep-95, J Love	CDFexport-related changes.  FSI key
18 *				definitions.
19 *   V1.2c 28-Sep-95, J Love	Macintosh dialog filtering.  Outline default
20 *				button.
21 *   V1.3  22-Aug-96, J Love	CDF V2.6.
22 *   V1.3a 21-Feb-97, J Love	Removed RICE.
23 *   V1.4b 16-Nov-97, J Love	Windows NT/Visual C++.
24 *   V1.5  11-Jul-05, M Liu      Added MingW port for PC.
25 *   V1.6  03-May-06, M Liu      Added checksum option for the files.
26 *   V1.7  13-Oct-06, M Liu      Changed to allow upper and lower case CDF
27 *                               name to be used on win32.
28 *   V3.3  10-Jan-09, M Liu      Validate a file before it is used.
29 *
30 ******************************************************************************/
31 
32 #define CDFEDIT
33 #include "cdfedit.h"
34 
35 #if defined(vms) || defined(unix) || defined(posixSHELL)
36 #define BROWSEaware 1
37 #else
38 #define BROWSEaware 0
39 #endif
40 
41 /******************************************************************************
42 * Increased stack size and overlay buffer for Borland C on IBM PC.
43 ******************************************************************************/
44 
45 #if defined(BORLANDC)
46 extern unsigned _stklen = BORLANDC_STACK_SIZE;
47 extern unsigned _ovrbuffer = BORLANDC_OVERLAY_SIZE;
48 #endif
49 
50 /******************************************************************************
51 * Global variables local to this source file.
52 ******************************************************************************/
53 
54 AOSs2A (openingLines, "Opening CDF...", "")
55 AOSs2B (closingLines, "Closing CDF...", "")
56 AOSs2C (delLines, "Deleting CDF...", "")
57 
58 /******************************************************************************
59 * Main.
60 ******************************************************************************/
61 
62 #if !defined(win32)
63 MAIN {
64   Logical success = TRUE;
65   strcpyX (pgmName, "CDFedit", MAX_PROGRAM_NAME_LEN);
66 #if defined(mac)
67   MacExecuteFSI (EditCDFs, EditQOPs);
68 #else
69   success = EditCDFs (argc, argv);
70 #endif
71 #if defined(DEBUG)
72   if (cdf_FreeMemory(NULL,FatalError) > 0) DisplayWarning ("Abandoned buffers.");
73 #else
74   cdf_FreeMemory (NULL, FatalError);
75 #endif
76   return BOO(success,EXIT_SUCCESS_,EXIT_FAILURE_);
77 }
78 #endif
79 
80 /******************************************************************************
81 * EditCDFs.
82 ******************************************************************************/
83 
EditCDFs(argC,argV)84 Logical EditCDFs (argC, argV)
85 int argC;
86 char *argV[];
87 {
88    QOP *qop;
89    static char *validQuals[] = {
90      "browse", "nobrowse", "zmode", "format", "noformat", "prompt",
91      "noprompt", "report", "neg2posfp0", "noneg2posfp0", "cache",
92      "statistics", "nostatistics", "gwithentries", "nogwithentries",
93      "vwithentries", "novwithentries", "about", NULL
94    };
95    static int optRequired[] = {
96      FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE,
97      FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0
98    };
99    static char *reportTokens[] = { "errors", "warnings", "informationals" };
100    char CDFspec[DU_MAX_PATH_LEN+1];
101    Logical useFormat, promptForSpec, negToPosFp0, status;
102    long zMode, workingCache, stageCache, compressCache;
103    Logical qopError = FALSE;
104    /***************************************************************************
105    * Check qualifiers/options/parameters.
106    ***************************************************************************/
107    switch (argC) {
108      case 1:
109        InitializeScreen ();
110        OnlineHelpWindow (olhFile, OLHhelpID);
111        CleanupScreen ();
112        return TRUE;
113      default:
114        qop = Qop (argC, argV, validQuals, optRequired);
115        if (qop == NULL) return FALSE;
116        /***********************************************************************
117        * Check for `about' qualifier.
118        ***********************************************************************/
119        if (qop->qualEntered[ABOUTqual]) {
120 	 DisplayIdentification (pgmName);
121 	 cdf_FreeMemory (qop, FatalError);
122 	 return TRUE;
123        }
124        /***********************************************************************
125        * Get CDF path parameter.
126        ***********************************************************************/
127        switch (qop->Nparms) {
128 	 case 0:
129 	   CDFspec[0] = NUL;
130 	   break;
131 	 case 1:
132 	   strcpyX (CDFspec, qop->parms[CDFSPECparm], DU_MAX_PATH_LEN);
133 #if defined(vms) || defined(dos)
134 	   MakeUpperString (CDFspec);
135 #endif
136 	   break;
137 	 default:
138 	   DisplayError ("Too many parameters.");
139 	   qopError = TRUE;
140 	   break;
141        }
142        /***********************************************************************
143        * Check for `browse', `format', `prompt', `neg2posfp0', and `statistics'
144        * qualfiers.
145        ***********************************************************************/
146        qopError = qopError | !TFqualifier(qop,&browseOnly,BROWSEqual,
147 					  NOBROWSEqual,DEFAULTbrowseEDIT,
148 					  "browse");
149        qopError = qopError | !TFqualifier(qop,&useFormat,FORMATqual,
150 					  NOFORMATqual,DEFAULTformatEDIT,
151 					  "format");
152        qopError = qopError | !TFqualifier(qop,&promptForSpec,PROMPTqual,
153 					  NOPROMPTqual,DEFAULTpromptEDIT,
154 					  "prompt");
155        qopError = qopError | !TFqualifier(qop,&negToPosFp0,NEG2POSFP0qual,
156 					  NONEG2POSFP0qual,DEFAULT_NEGtoPOSfp0,
157 					  "neg2posfp0");
158        qopError = qopError | !TFqualifier(qop,&dumpStatistics,STATSqual,
159 					  NOSTATSqual,DEFAULTstatsEDIT,
160 					  "statistics");
161        qopError = qopError | !TFqualifier(qop,&gAttrsAndEntries,gWITHqual,
162 					  NOgWITHqual,DEFAULTgWithEDIT,
163 					  "gwithentries");
164        qopError = qopError | !TFqualifier(qop,&vAttrsAndEntries,vWITHqual,
165 					  NOvWITHqual,DEFAULTvWithEDIT,
166 					  "vwithentries");
167        /***********************************************************************
168        * Check for zMode qualifier.
169        ***********************************************************************/
170        if (qop->qualEntered[ZMODEqual]) {
171 	 switch (qop->qualOpt[ZMODEqual][0]) {
172 	   case '0': zMode = zMODEoff; break;
173 	   case '1': zMode = zMODEon1; break;
174 	   case '2': zMode = zMODEon2; break;
175 	   default: {
176 	     char tempS[MAX_MESSAGE_TEXT_LEN+1];
177 	     sprintf (tempS, "Illegal zMode (%s).", qop->qualOpt[ZMODEqual]);
178 	     DisplayError (tempS);
179 	     qopError = TRUE;
180 	   }
181 	 }
182        }
183        else
184 	 zMode = DEFAULTzModeEDIT;
185        /***********************************************************************
186        * Check for `cache' qualifier.
187        ***********************************************************************/
188        if (qop->qualEntered[CACHEqual]) {
189 	 if (!ParseCacheSizes(qop->qualOpt[CACHEqual],
190 			      &workingCache,&stageCache,&compressCache)) {
191 	   DisplayError ("Illegal cache size/type.");
192 	   qopError = TRUE;
193 	 }
194        }
195        else {
196 	 workingCache = useDEFAULTcacheSIZE;
197 	 stageCache = useDEFAULTcacheSIZE;
198 	 compressCache = useDEFAULTcacheSIZE;
199        }
200        /***********************************************************************
201        * Check for `report' qualifier.  If absent, use defaults.
202        ***********************************************************************/
203        if (qop->qualEntered[REPORTqual]) {
204 	 if (!ParseOptionList(3,reportTokens,
205 			      qop->qualOpt[REPORTqual],report)) {
206 	   DisplayError ("Illegal list of `report' options.");
207 	   qopError = TRUE;
208 	 }
209        }
210        else {
211 	 report[ERRORs] = REPORTerrorsDEFAULT;
212 	 report[WARNs] = REPORTwarningsDEFAULT;
213 	 report[INFOs] = REPORTinfosDEFAULT;
214        }
215        /***********************************************************************
216        * Check for missing/conflicting parameters/qualifiers.
217        ***********************************************************************/
218        if (qop->Nparms < 1 && (!promptForSpec)) {
219 	 DisplayError ("Enter CDF(s) specification or `prompt' qualifier.");
220 	 qopError = TRUE;
221        }
222        /***********************************************************************
223        * Free QOP memory and check for an error.
224        ***********************************************************************/
225        cdf_FreeMemory (qop, FatalError);
226        if (qopError) return FALSE;
227        break;
228    }
229    /***************************************************************************
230    * Initialize.
231    ***************************************************************************/
232    if (browseOnly) {
233      strcpyX (pgmName, "CDFbrowse", MAX_PROGRAM_NAME_LEN);
234      strcpyX (ilhFile, "cdfbrow.ilh", MAX_ILHFILE_LEN);
235    }
236    else
237      strcpyX (ilhFile, "cdfedit.ilh", MAX_ILHFILE_LEN);
238    InitializeScreen ();
239    /***************************************************************************
240    * Edit CDF(s).
241    ***************************************************************************/
242    CDFsetValidate (VALIDATEFILEon);
243    if (promptForSpec)
244      status = SpecificationPrompt (CDFspec, useFormat, negToPosFp0, zMode,
245 				   workingCache, stageCache, compressCache);
246    else
247      if (IsDir(CDFspec) || IsWild(CDFspec))
248        status = EditCDFsMenu (CDFspec, negToPosFp0, useFormat, zMode,
249 			      workingCache, stageCache, compressCache);
250      else
251        status = TryToEditCDF (CDFspec, negToPosFp0, useFormat, zMode,
252 			      workingCache, stageCache, compressCache);
253    /***************************************************************************
254    * Clean up screen and return.
255    ***************************************************************************/
256    CleanupScreen ();
257    return status;
258 }
259 
260 /******************************************************************************
261 * SpecificationPrompt.
262 ******************************************************************************/
263 
SpecificationPrompt(CDFspec,useFormat,negToPosFp0,zMode,workingCache,stageCache,compressCache)264 Logical SpecificationPrompt (CDFspec, useFormat, negToPosFp0, zMode,
265 			     workingCache, stageCache, compressCache)
266 char CDFspec[DU_MAX_PATH_LEN+1];
267 Logical useFormat;
268 Logical negToPosFp0;
269 long zMode;
270 long workingCache;
271 long stageCache;
272 long compressCache;
273 {
274   for (;;) {
275     if (NULstring(CDFspec)) strcpyX (CDFspec,CURRENTDIRECTORY,DU_MAX_PATH_LEN);
276     if (!PromptForSpec(CDFspec)) break;
277 #if defined(vms) || defined(dos)
278     MakeUpperString (CDFspec);
279 #endif
280     if (IsDir(CDFspec) || IsWild(CDFspec)) {
281       /************************************************************************
282       * Directory/wildcard (more than one CDF).
283       ************************************************************************/
284       if (!EditCDFsMenu(CDFspec,negToPosFp0,useFormat,
285 			zMode,workingCache,stageCache,
286 			compressCache)) return FALSE;
287     }
288     else {
289       /************************************************************************
290       * Assumed to be a complete specification of a single CDF.
291       ************************************************************************/
292       TryToEditCDF (CDFspec, negToPosFp0, useFormat, zMode, workingCache,
293 		    stageCache, compressCache);
294     }
295   }
296   return TRUE;
297 }
298 
299 /******************************************************************************
300 * EditCDFsMenu.
301 ******************************************************************************/
302 
EditCDFsMenu(CDFspec,negToPosFp0,useFormat,zMode,workingCache,stageCache,compressCache)303 Logical EditCDFsMenu (CDFspec, negToPosFp0, useFormat, zMode, workingCache,
304 		      stageCache, compressCache)
305 char *CDFspec;
306 Logical negToPosFp0;
307 Logical useFormat;
308 long zMode;
309 long workingCache;
310 long stageCache;
311 long compressCache;
312 {
313   CDFstatus status; int nCDFs;
314   char **dirS, **CDFs;
315   char CDFdir[DU_MAX_DIR_LEN+1], CDFname[DU_MAX_NAME_LEN+1];
316   char CDFpathT[DU_MAX_PATH_LEN+1];
317   char CDFfullPath[DU_MAX_PATH_LEN+1];
318   static char label[16+DU_MAX_PATH_LEN+2+1];
319   static Logical first = TRUE;
320   AOSs1 (header, BLANKs78)
321   AOSs2 (trailerEdit,
322 	 "Edit:   ________   Exit:   ________   Help: ________",
323 	 "Create: ________   Delete: ________   Info: ________")
324   AOSs1A (trailerBrowse,
325 	  "Browse: ________  Exit: ________  Info: ________  Help: ________")
326   static int exitCharsEdit[] = {
327     ENTERkey_FSI, EXITkey_FSI, CREATECDFkey_EDIT, DELETECDFkey_EDIT,
328     HELPkey_FSI, INFOkey_EDIT, NUL
329   };
330   static int exitCharsBrowse[] = {
331     ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, INFOkey_EDIT, NUL
332   };
333   static struct ItemWindowStruct IW = {
334      0, 0, 80, label, 1, header, 0, NULL, 0, NULL, NULL, NULL, 0, 0, NULL,
335      NULL, REFRESHkey_FSI, TRUE, NSkey_FSI, PSkey_FSI
336   };
337   AOSs6 (infoLines, BLANKs78, BLANKs78, BLANKs78,
338 	 " ", "Enter any key to continue...", "")
339   static char noneMsg[] = {
340     "No CDF selected (no CDFs exist for this specification)."
341   };
342   /****************************************************************************
343   * First time...
344   ****************************************************************************/
345   if (first) {
346     EncodeKeyDefinitions (1, trailerBrowse, ENTERkey_FSI, EXITkey_FSI,
347 			    INFOkey_EDIT, HELPkey_FSI);
348     EncodeKeyDefinitions (2, trailerEdit, ENTERkey_FSI, EXITkey_FSI,
349 			    HELPkey_FSI, CREATECDFkey_EDIT, DELETECDFkey_EDIT,
350 			    INFOkey_EDIT);
351     first = FALSE;
352   }
353   if (browseOnly) {
354     IW.NiRows = 15;
355     IW.NtLines = 1;
356     IW.tLines = trailerBrowse;
357     IW.exitChars = exitCharsBrowse;
358   }
359   else {
360     IW.NiRows = 14;
361     IW.NtLines = 2;
362     IW.tLines = trailerEdit;
363     IW.exitChars = exitCharsEdit;
364   }
365 
366   ParsePath (CDFspec, CDFdir, CDFname);
367   BuildCDFsMenu (CDFspec, &nCDFs, &dirS, &CDFs, &IW);
368   ItemWindow (NEWiw, &IW, 0);
369   for (;;) {
370      ItemWindow (READiw, &IW);
371      switch (IW.key) {
372        /***********************************************************************
373        * Edit currently selected CDF.  The CDFs menu is rebuild/updated in
374        * case the CDF was deleted.  When the CDFs menu is updated, the new
375        * current item is set to the old current item (or the last item in
376        * case more than one CDF was deleted [possibly by another user]).
377        * If the CDF was deleted, the new current item should be the CDF
378        * that followed it in the list (unless it was the last CDF in which
379        * case the new current item will be the last CDF in the new list).
380        ***********************************************************************/
381        case ENTERkey_FSI:
382 	 if (IW.nItems == 0) {
383 	   ProblemWindow (noneMsg, FALSE);
384 	 }
385 	 else {
386 	   CDFid id; int lastItemN;
387 	   Logical isLFS;
388 	   strcpyX (CDFpathT, dirS[IW.itemN], DU_MAX_PATH_LEN);
389 	   AppendToDir (CDFpathT, CDFs[IW.itemN]);
390 	   status = CheckLFS (CDFpathT, &isLFS, CDFfullPath);
391 	   compressed = CompressedCDF (CDFfullPath);
392 	   if (compressed) {
393 	     MessageWindow (openingLines, NULL, LogicalFALSE);
394 	     zzzzz (1.0);
395 	   }
396 	   status = CDFlib (OPEN_, CDF_, CDFfullPath, &id,
397 			    NULL_);
398 	   if (compressed) MessageWindow (NULL);
399 	   ReportStatus (status, FALSE);
400 	   if (StatusBAD(status)) break;
401 	   ItemWindow (UNDISPLAYiw, &IW);
402 	   EditCDF (CDFs[IW.itemN], useFormat, workingCache, stageCache,
403 		    compressCache, zMode, negToPosFp0);
404 	   FreeCDFsMenu (dirS, CDFs, &IW);
405 	   BuildCDFsMenu (CDFspec, &nCDFs, &dirS, &CDFs, &IW);
406 	   lastItemN = IW.nItems - 1;
407 	   ItemWindow (UPDATEiw, &IW, MINIMUM(IW.itemN,lastItemN));
408 	   ItemWindow (REDISPLAYiw, &IW);
409 	 }
410 	 break;
411        /***********************************************************************
412        * Display `info' for currently selected CDF.
413        ***********************************************************************/
414        case INFOkey_EDIT:
415 	 if (IW.nItems == 0) {
416 	   ProblemWindow (noneMsg, FALSE);
417 	 }
418 	 else {
419 	   long cType, cParms[CDF_MAX_PARMS], cFileSize1, uFileSize1;
420 	   OFF_T cFileSize2, uFileSize2;
421 	   Logical isLFS;
422 	   strcpyX (CDFpathT, dirS[IW.itemN], DU_MAX_PATH_LEN);
423 	   AppendToDir (CDFpathT, CDFs[IW.itemN]);
424 	   status = CheckLFS(CDFpathT, &isLFS, CDFfullPath);
425 	   if (isLFS)
426 	     status = CDFlib (GET_, CDF_INFO_, CDFfullPath, &cType, cParms,
427 					       &cFileSize1, &uFileSize1,
428 			      NULL_);
429 	   else
430              status = CDFlib (GET_, CDF_INFO_, CDFfullPath, &cType, cParms,
431                                                &cFileSize2, &uFileSize2,
432                               NULL_);
433 	   ReportStatus (status, FALSE);
434 	   if (StatusOK(status)) {
435 	     char label[DU_MAX_NAME_LEN+13+1];
436 	     sprintf (label, " Info for `%s' ", CDFs[IW.itemN]);
437 	     sprintf (infoLines[0], "Compression:  %s",
438 		      CompressionToken(cType,cParms));
439 	     if (cType == NO_COMPRESSION) {
440 	       if (isLFS)
441 #if !defined(win32)
442 	         sprintf (infoLines[1], "Uncompressed: %lld bytes", uFileSize2);
443 #else
444                  sprintf (infoLines[1], "Uncompressed: %I64d bytes", uFileSize2);
445 #endif
446 	       else
447 		 sprintf (infoLines[1], "Uncompressed: %ld bytes", uFileSize1);
448 	       MakeNUL (infoLines[2]);
449 	     }
450 	     else {
451 	       if (isLFS) {
452 #if !defined(win32)
453                  sprintf (EofS(infoLines[0]), " (%ld%%)",
454                           (long) (((OFF_T)100 * cFileSize2) / uFileSize2));
455 	         sprintf (infoLines[1], "Compressed:   %lld bytes", cFileSize2);
456 	         sprintf (infoLines[2], "Uncompressed: %lld bytes", uFileSize2);
457 #else
458                  sprintf (EofS(infoLines[0]), " (%ld%%)",
459                           (long) (((OFF_T)100 * cFileSize2) / uFileSize2));
460                  sprintf (infoLines[1], "Compressed:   %I64d bytes", cFileSize2);
461                  sprintf (infoLines[2], "Uncompressed: %I64d bytes", uFileSize2);
462 #endif
463 	       } else {
464 		 sprintf (EofS(infoLines[0]), " (%ld%%)",
465 			 ((100L * cFileSize1) / uFileSize1));
466 		 sprintf (infoLines[1], "Compressed:   %ld bytes", cFileSize1);
467 		 sprintf (infoLines[2], "Uncompressed: %ld bytes", uFileSize1);
468 	       }
469 	     }
470 	     MessageWindow (infoLines, label, LogicalTRUE);
471 	     MessageWindow (NULL);
472 	   }
473 	 }
474 	 break;
475        /***********************************************************************
476        * Create a CDF.
477        * Note that `CreateCDF' will undisplay this window (if necessary).
478        ***********************************************************************/
479        case CREATECDFkey_EDIT: {
480 	 char CDFnameT[DU_MAX_NAME_LEN+1]; int itemN;
481 	 strcpyX (CDFnameT, "", DU_MAX_NAME_LEN);
482 	 CreateCDF (CDFdir, CDFnameT, zMode, useFormat, negToPosFp0,
483 		    workingCache, stageCache, compressCache, &IW);
484 	 FreeCDFsMenu (dirS, CDFs, &IW);
485 	 BuildCDFsMenu (CDFspec, &nCDFs, &dirS, &CDFs, &IW);
486 	 itemN = IndexInList (CDFnameT, nCDFs, CDFs);
487 	 ItemWindow (UPDATEiw, &IW, BOO(itemN < 0,0,itemN));
488 	 ItemWindow (REDISPLAYiw, &IW);
489 	 break;
490        }
491        /***********************************************************************
492        * Delete currently selected CDF.  When the CDFs menu is updated, the
493        * new current item is set to the old current item (or the last item
494        * in case more than one CDF was deleted [possibly by another user]).
495        * The new current item should be the CDF (in the list) that followed
496        * the CDF that was deleted (unless it was the last CDF in which case
497        * the new current item will be the last CDF in the new list).
498        ***********************************************************************/
499        case DELETECDFkey_EDIT:
500 	 if (IW.nItems == 0) {
501 	   ProblemWindow (noneMsg, FALSE);
502 	 }
503 	 else {
504 	   char delim, question[DU_MAX_NAME_LEN+15+1];
505 	   delim = PickDelimiter (CDFs[IW.itemN],strlen(CDFs[IW.itemN]));
506 	   sprintf (question, "Delete CDF %c%s%c ?", delim, CDFs[IW.itemN],
507 		    delim);
508 	   if (ConfirmWindow(3,78,question,NULL,FALSE,DELETECDFhelpID)) {
509 	     CDFid id; CDFstatus status; int lastItemN;
510 	     Logical isLFS;
511 	     strcpyX (CDFpathT, dirS[IW.itemN], DU_MAX_PATH_LEN);
512 	     AppendToDir (CDFpathT, CDFs[IW.itemN]);
513              status = CheckLFS (CDFpathT, &isLFS, CDFfullPath);
514              compressed = CompressedCDF (CDFfullPath);
515 	     if (compressed) {
516 	       MessageWindow (delLines, NULL, LogicalFALSE);
517 	       zzzzz (1.0);
518 	     }
519 	     status = CDFlib (OPEN_, CDF_, CDFfullPath, &id,
520 			      DELETE_, CDF_,
521 			      NULL_);
522 	     if (compressed) MessageWindow (NULL);
523 	     ReportStatus (status, FALSE);
524 	     FreeCDFsMenu (dirS, CDFs, &IW);
525 	     BuildCDFsMenu (CDFspec, &nCDFs, &dirS, &CDFs, &IW);
526 	     lastItemN = IW.nItems - 1;
527 	     ItemWindow (UPDATEiw, &IW, MINIMUM(IW.itemN,lastItemN));
528 	   }
529 	 }
530 	 break;
531        /***********************************************************************
532        * Display online help.
533        ***********************************************************************/
534        case HELPkey_FSI:
535 	 OnlineHelpWindow (ilhFile, CDFShelpID);
536 	 break;
537        /***********************************************************************
538        * Exit.
539        ***********************************************************************/
540        case EXITkey_FSI:
541 	 ItemWindow (DELETEiw, &IW);
542 	 FreeCDFsMenu (dirS, CDFs, &IW);
543 	 return TRUE;
544      }
545   }
546 }
547 
548 /******************************************************************************
549 * BuildCDFsMenu.
550 ******************************************************************************/
551 
BuildCDFsMenu(CDFspec,nCDFs,dirS,CDFs,IW)552 void BuildCDFsMenu (CDFspec, nCDFs, dirS, CDFs, IW)
553 char *CDFspec;
554 int *nCDFs;
555 char ***dirS;
556 char ***CDFs;
557 struct ItemWindowStruct *IW;
558 {
559   int CDFn;
560   sprintf (IW->label, " Specification \"%s\" ", CDFspec);
561   *nCDFs = CDFdirList (CDFspec, dirS, CDFs);
562   sprintf (IW->hLines[0], "%d CDF%s", *nCDFs, (*nCDFs == 1 ? "" : "s"));
563   if (*nCDFs > 0) {
564     AllocIW (IW, *nCDFs, *nCDFs, CDFs_NAME_LEN, FatalError);
565     for (CDFn = 0; CDFn < *nCDFs; CDFn++) {
566        size_t nameLen = strlen((*CDFs)[CDFn]);
567        strcpyX (IW->iLines[CDFn], (*CDFs)[CDFn], CDFs_NAME_LEN);
568        IW->iLineNs[CDFn] = CDFn;
569        IW->iCols[CDFn] = 0;
570        IW->iLens[CDFn] = (int) MINIMUM(CDFs_NAME_LEN,nameLen);
571     }
572   }
573   else {
574     IW->NiLines = 0;
575     IW->nItems = 0;
576   }
577   return;
578 }
579 
580 /******************************************************************************
581 * FreeCDFsMenu.
582 ******************************************************************************/
583 
FreeCDFsMenu(dirS,CDFs,IW)584 void FreeCDFsMenu (dirS, CDFs, IW)
585 char **dirS;
586 char **CDFs;
587 struct ItemWindowStruct *IW;
588 {
589   if (dirS != NULL) cdf_FreeMemory (dirS, FatalError);
590   if (CDFs != NULL) cdf_FreeMemory (CDFs, FatalError);
591   FreeIW (IW, FatalError);
592   return;
593 }
594 
595 /******************************************************************************
596 * TryToEditCDF.
597 ******************************************************************************/
598 
TryToEditCDF(CDFspec,negToPosFp0,useFormat,zMode,workingCache,stageCache,compressCache)599 Logical TryToEditCDF (CDFspec, negToPosFp0, useFormat, zMode, workingCache,
600 		      stageCache, compressCache)
601 char *CDFspec;
602 Logical negToPosFp0;
603 Logical useFormat;
604 long zMode;
605 long workingCache;
606 long stageCache;
607 long compressCache;
608 {
609   CDFstatus status; CDFid id;
610   char CDFdir[DU_MAX_DIR_LEN+1], CDFname[DU_MAX_NAME_LEN+1];
611   char CDFfullName[DU_MAX_NAME_LEN+1];
612   Logical isLFS;
613   ParsePath (CDFspec, CDFdir, CDFname);
614   status = CheckLFS (CDFspec, &isLFS, CDFfullName);
615   compressed = FALSE;
616   if (status == CDF_OK) {
617     compressed = CompressedCDF (CDFfullName);
618     if (compressed) {
619       MessageWindow (openingLines, NULL, LogicalFALSE);
620       zzzzz (1.0);
621     }
622   }
623   status = CDFlib (OPEN_, CDF_, CDFfullName, &id,
624 		   NULL_);
625   if (compressed) MessageWindow (NULL);
626   switch (status) {
627     case NO_SUCH_CDF:
628       if (!browseOnly) {
629 	char delim, question[DU_MAX_PATH_LEN+29+1];
630 	int helpID;
631 	delim = PickDelimiter(CDFfullName, strlen(CDFfullName));
632 	if (CDFgetFileBackwardEnvVar() == 1) {
633 	  sprintf (question, "CDF %c%s%c does not exist.  Create?", delim,
634 	           CDFfullName, delim);
635 	} else {
636 	  sprintf (question, "CDF %c%s%c does not exist.  Create(V3 or V2.7)?", delim,
637 		   CDFfullName, delim);
638 	  helpID = CREATECDFV23helpID;
639 	}
640 	if (ConfirmWindow2(3,78,question,NULL,TRUE,helpID)) {
641 	  if (!CreateCDF(CDFdir,CDFname,zMode,
642 			 useFormat,negToPosFp0,
643 			 workingCache, stageCache,
644 			 compressCache,NULL)) return FALSE;
645 	}
646       }
647       else
648 	ProblemWindow ("CDF does not exist.", TRUE);
649       break;
650     default:
651       ReportStatus (status, TRUE);
652       if (StatusBAD(status)) return FALSE;
653       if (!EditCDF(CDFname,useFormat,workingCache,stageCache,
654 		   compressCache,zMode,negToPosFp0)) return FALSE;
655       break;
656   }
657   return TRUE;
658 }
659 
660 /******************************************************************************
661 * CreateCDF.
662 ******************************************************************************/
663 
CreateCDF(CDFdir,CDFname,zMode,useFormat,negToPosFp0,workingCache,stageCache,compressCache,IWcdfs)664 Logical CreateCDF (CDFdir, CDFname, zMode, useFormat, negToPosFp0,
665 		   workingCache, stageCache, compressCache, IWcdfs)
666 char *CDFdir;           /* Directory in which to create CDF. */
667 char *CDFname;          /* If null-string (""), then prompt for name.  Returns
668 			   name entered here. */
669 long zMode;             /* The zMode to select after CDF is created. */
670 Logical useFormat;      /* TRUE if FORMAT attribute should be used. */
671 Logical negToPosFp0;    /* TRUE if conversion of -0.0 to +0.0 should be
672 			   selected after CDF is created. */
673 long workingCache;      /* Number of cache buffers for the "working" dotCDF
674 			   file. */
675 long stageCache;	/* Number of cache buffers for the staging file. */
676 long compressCache;	/* Number of cache buffers for the compression scratch
677 			   file. */
678 struct ItemWindowStruct *IWcdfs;
679 			/* Pointer to "CDFs Menu" widget.  If NULL, then this
680 			   routine was not called from the "CDFs Menu". */
681 {
682   CDFstatus status; CDFid id; static Logical first = TRUE;
683   long numDims, dimSizes[CDF_MAX_DIMS];
684   char CDFpathT[DU_MAX_PATH_LEN+1], delim;
685   AOSs1 (trailer, "Enter: ________   Exit: ________   Help: ________")
686   static int exitChars[] = { ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NUL };
687   static char *headerDim[] = {
688     "Enter rVariable dimensionality...",
689     "Syntax: <numDims>:[<dimSize1>,<dimSize2>,...,<dimSizeN>]",
690     "Examples: 0:[], 1:[5], 2:[100,100], 3:[10,20,30]"
691   };
692   static char valueDim[MAX_DIMENSIONALITY_LEN+1];
693   static char labelDim[8+DU_MAX_NAME_LEN+1];
694   static struct PromptWindowStruct PWdim = {
695     labelDim, 3, 1, 78, 3, headerDim, MAX_DIMENSIONALITY_LEN, valueDim,
696     1, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI,
697     INSERTorOVERkey_FSI
698   };
699   if (first) {
700     EncodeKeyDefinitions (1, trailer, ENTERkey_FSI, EXITkey_FSI,
701 			  HELPkey_FSI);
702     first = FALSE;
703   }
704   if (NULstring(CDFname)) {
705     static char *header[] = {
706       "Enter CDF name (without delimiters)...",
707       "Syntax: <char1><char2>...<charN>",
708       "Example: D104B"
709     };
710     static char label[13+1+DU_MAX_DIR_LEN+1+1+1];
711     static struct PromptWindowStruct PW = {
712       label, 3, 1, 78, 3, header, DU_MAX_NAME_LEN, NULL, 1, trailer,
713       exitChars, REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI,
714       INSERTorOVERkey_FSI
715     };
716     char dirT[DU_MAX_DIR_LEN+1];
717     strcpyX (dirT, (NULstring(CDFdir) ? CURRENTDIRECTORY : CDFdir),
718 	     DU_MAX_DIR_LEN);
719     delim = PickDelimiter (dirT, strlen(dirT));
720     sprintf (PW.label, " Creating in %c%s%c ", delim, dirT, delim);
721     PW.value = CDFname;
722     PromptWindow (NEWpw, &PW, 0, LogicalTRUE);
723     for (;;) {
724        if (EnterPW(&PW,CDFNAMEhelpID))
725 	 if (strlen(CDFname) > (size_t) 0) {
726 #if defined(vms) || defined(dos)
727 	   MakeUpperString (CDFname);
728 #endif
729 	   begin_pasteboard_update ();		/* Used to prevent the flicker
730 						   between this prompt and the
731 						   next one. */
732 	   PromptWindow (DELETEpw, &PW);
733 	   break;
734 	 }
735 	 else
736 	   ProblemWindow ("Illegal CDF name.", FALSE);
737        else {
738 	 PromptWindow (DELETEpw, &PW);
739 	 return TRUE;
740        }
741     }
742   }
743   strcpyX (CDFpathT, CDFdir, DU_MAX_PATH_LEN);
744   AppendToDir (CDFpathT, CDFname);
745   strcpyX (PWdim.value, "0:[]", MAX_DIMENSIONALITY_LEN);
746   delim = PickDelimiter (CDFname, strlen(CDFname));
747   sprintf (labelDim, " CDF %c%s%c ", delim, CDFname, delim);
748   PromptWindow (NEWpw, &PWdim, (int) strlen(PWdim.value), LogicalTRUE);
749   end_pasteboard_update ();	/* It is OK to call this in the case where
750 				   the `begin_pasteboard_update' above was
751 				   not called (because the CDF name was not
752 				   prompted for. */
753   for (;;) {
754      if (EnterPW(&PWdim,RDIMhelpID)) {
755        if (DecodeDimensionality(PWdim.value,&numDims,dimSizes)) {
756 	 PromptWindow (DELETEpw, &PWdim);
757 	 break;
758        }
759        else
760 	 ProblemWindow ("Illegal dimensionality.", FALSE);
761      }
762      else {
763        PromptWindow (DELETEpw, &PWdim);
764        return TRUE;
765      }
766   }
767   status = CDFlib (CREATE_, CDF_, CDFpathT, numDims, dimSizes, &id,
768 		   NULL_);
769   ReportStatus (status, FALSE);
770   if (StatusBAD(status)) return FALSE;
771   compressed = FALSE;
772   if (IWcdfs != NULL) ItemWindow (UNDISPLAYiw, IWcdfs);
773   return EditCDF(CDFname,useFormat,workingCache,stageCache,compressCache,
774 		 zMode,negToPosFp0);
775 }
776 
777 /******************************************************************************
778 * EditCDF.
779 ******************************************************************************/
780 
EditCDF(CDFname,useFormat,workingCache,stageCache,compressCache,zMode,negToPosFp0)781 Logical EditCDF (CDFname, useFormat, workingCache, stageCache, compressCache,
782 		 zMode, negToPosFp0)
783 char *CDFname;
784 Logical useFormat;
785 long workingCache;
786 long stageCache;
787 long compressCache;
788 long zMode;
789 Logical negToPosFp0;
790 {
791   Logical status, closed = FALSE;
792   /****************************************************************************
793   * Edit the CDF.
794   ****************************************************************************/
795   status = EditCDFx(CDFname,useFormat,workingCache,stageCache,compressCache,
796 		    zMode,negToPosFp0,&closed);
797   if (!closed) CDFlib (CLOSE_, CDF_,
798 		       NULL_);
799   /****************************************************************************
800   * Return the conversion status.
801   ****************************************************************************/
802   return status;
803 }
804 
805 /******************************************************************************
806 * EditCDFx.
807 ******************************************************************************/
808 
EditCDFx(CDFname,useFormat,workingCache,stageCache,compressCache,zMode,negToPosFp0,closed)809 Logical EditCDFx (CDFname, useFormat, workingCache, stageCache, compressCache,
810 		  zMode, negToPosFp0, closed)
811 char *CDFname;
812 Logical useFormat;
813 long workingCache;
814 long stageCache;
815 long compressCache;
816 long zMode;
817 Logical negToPosFp0;
818 Logical *closed;
819 {
820    CDFstatus status;
821    long readonlyMode = BOO(browseOnly,READONLYon,READONLYoff);
822    long negToPosFp0Mode = BOO(negToPosFp0,NEGtoPOSfp0on,NEGtoPOSfp0off);
823    AOSs3 (hLines, BLANKs78, BLANKs78, BLANKs78)
824    static Logical first = TRUE;
825    static char *iLinesBrowse[] = {
826      "<Browse zVariables>",
827      "<Browse rVariables>",
828      "<Browse gAttributes>",
829      "<Browse vAttributes>"
830    };
831    static char *iLinesEdit[] = {
832      "<Edit zVariables>   <Change compression>   <Change checksum>",
833      "<Edit rVariables>   <Change encoding>",
834      "<Edit gAttributes>  <Change majority>",
835      "<Edit vAttributes>  <Change format>"
836    };
837    AOSs1A (tLinesBrowse,
838    "Select: ________   Exit: ________   Help: ________")
839    AOSs1B (tLinesEdit,
840    "Select: ________   Delete: ________   Exit: ________   Help: ________")
841    static int iLineNsBrowse[] = { 0, 1, 2, 3 };
842    static int iColsBrowse[] = { 0, 0, 0, 0 };
843    static int iLensBrowse[] = { 19, 19, 20, 20 };
844    static int iLineNsEdit[] = { 0, 0, 0, 1, 1, 2, 2, 3, 3 };
845    static int iColsEdit[] = { 0, 20, 43, 0, 20, 0, 20, 0, 20 };
846    static int iLensEdit[] = { 17, 20, 17, 17, 17, 18, 17, 18, 15 };
847    static int exitCharsBrowse[] = {
848      ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, zMODE0key_EDIT, zMODE1key_EDIT,
849      zMODE2key_EDIT, NUL
850    };
851    static int exitCharsEdit[] = {
852      ENTERkey_FSI, EXITkey_FSI, DELETECDFkey_EDIT, HELPkey_FSI,
853      zMODE0key_EDIT, zMODE1key_EDIT, zMODE2key_EDIT, NUL };
854    static char label[6+DU_MAX_NAME_LEN+2+1];
855    static struct ItemWindowStruct IW = {
856       0, 0, 80, label, 3, hLines, 0, NULL, 0, NULL, NULL, NULL, 4,
857       1, NULL, NULL, REFRESHkey_FSI, FALSE, NUL, NUL
858    };
859    /***************************************************************************
860    * First time...
861    ***************************************************************************/
862    if (first) {
863      EncodeKeyDefinitions (1, tLinesBrowse, ENTERkey_FSI, EXITkey_FSI,
864 			     HELPkey_FSI);
865      EncodeKeyDefinitions (1, tLinesEdit, ENTERkey_FSI, DELETECDFkey_EDIT,
866 			     EXITkey_FSI, HELPkey_FSI);
867      first = FALSE;
868    }
869    if (browseOnly) {
870      IW.NiLines = 4;
871      IW.iLines = iLinesBrowse;
872      IW.nItems = 4;
873      IW.iLineNs = iLineNsBrowse;
874      IW.iCols = iColsBrowse;
875      IW.iLens = iLensBrowse;
876      IW.tLines = tLinesBrowse;
877      IW.exitChars = exitCharsBrowse;
878    }
879    else {
880      IW.NiLines = 4;
881      IW.iLines = iLinesEdit;
882      IW.nItems = 9;
883      IW.iLineNs = iLineNsEdit;
884      IW.iCols = iColsEdit;
885      IW.iLens = iLensEdit;
886      IW.tLines = tLinesEdit;
887      IW.exitChars = exitCharsEdit;
888    }
889    /***************************************************************************
890    * Try to set number of cache buffers for dotCDF file, read-only mode, zMode,
891    * and -0.0 mode.
892    ***************************************************************************/
893    status = CDFlib (SELECT_, CDF_CACHESIZE_, workingCache,
894 			     STAGE_CACHESIZE_, stageCache,
895 			     COMPRESS_CACHESIZE_, compressCache,
896 			     CDF_READONLY_MODE_, readonlyMode,
897 			     CDF_zMODE_, zMode,
898 			     CDF_NEGtoPOSfp0_MODE_, negToPosFp0Mode,
899 		    NULL_);
900    if (!ReportStatus(status,FALSE)) return FALSE;
901    /***************************************************************************
902    * Build main menu.
903    ***************************************************************************/
904    if (!BuildCDFmenu(CDFname,&IW)) return FALSE;
905    /***************************************************************************
906    * Display menu/process keystrokes.
907    ***************************************************************************/
908    ItemWindow (NEWiw, &IW, 0);
909    for (;;) {
910      ItemWindow (READiw, &IW);
911      switch (IW.key) {
912        /***********************************************************************
913        * Perform selected function.
914        ***********************************************************************/
915        case ENTERkey_FSI: {
916 	 int itemNt = IW.itemN + BOO(browseOnly,BROWSEinOFFSET,0);
917 	 switch (itemNt) {
918 	   /*******************************************************************
919 	   * Edit rVariables.
920 	   *******************************************************************/
921 	   case EDITrVarsIN:
922 	   case BROWSErVarsIN:
923 	   case EDITzVarsIN:
924 	   case BROWSEzVarsIN: {
925 	     Logical zOp = (itemNt == EDITzVarsIN || itemNt == BROWSEzVarsIN);
926 	     ItemWindow (UNDISPLAYiw, &IW);
927 	     if (!EditVars(zOp,CDFname,useFormat)) {
928 	       ItemWindow (DELETEiw, &IW);
929 	       return FALSE;
930 	     }
931 	     if (!BuildCDFmenu(CDFname,&IW)) {
932 	       ItemWindow (DELETEiw, &IW);
933 	       return FALSE;
934 	     }
935 	     ItemWindow (UPDATEiw, &IW, IW.itemN);
936 	     ItemWindow (REDISPLAYiw, &IW);
937 	     break;
938 	   }
939 	   /*******************************************************************
940 	   * Edit gAttributes.
941 	   *******************************************************************/
942 	   case EDITgAttrsIN:
943 	   case BROWSEgAttrsIN:
944 	     ItemWindow (UNDISPLAYiw, &IW);
945 	     if (gAttrsAndEntries) {
946 	       if (!EditAttrs(TRUE,CDFname)) {
947 		 ItemWindow (DELETEiw, &IW);
948 		 return FALSE;
949 	       }
950 	     }
951 	     else {
952 	       if (!EditAttrsX(TRUE,CDFname)) {
953 		 ItemWindow (DELETEiw, &IW);
954 		 return FALSE;
955 	       }
956 	     }
957 	     if (!BuildCDFmenu(CDFname,&IW)) {
958 	       ItemWindow (DELETEiw, &IW);
959 	       return FALSE;
960 	     }
961 	     ItemWindow (UPDATEiw, &IW, IW.itemN);
962 	     ItemWindow (REDISPLAYiw, &IW);
963 	     break;
964 	   /*******************************************************************
965 	   * Edit vAttributes.
966 	   *******************************************************************/
967 	   case EDITvAttrsIN:
968 	   case BROWSEvAttrsIN:
969 	     ItemWindow (UNDISPLAYiw, &IW);
970 	     if (vAttrsAndEntries) {
971 	       if (!EditAttrs(FALSE,CDFname)) {
972 		 ItemWindow (DELETEiw, &IW);
973 		 return FALSE;
974 	       }
975 	     }
976 	     else {
977 	       if (!EditAttrsX(FALSE,CDFname)) {
978 		 ItemWindow (DELETEiw, &IW);
979 		 return FALSE;
980 	       }
981 	     }
982 	     if (!BuildCDFmenu(CDFname,&IW)) {
983 	       ItemWindow (DELETEiw, &IW);
984 	       return FALSE;
985 	     }
986 	     ItemWindow (UPDATEiw, &IW, IW.itemN);
987 	     ItemWindow (REDISPLAYiw, &IW);
988 	     break;
989 	   /*******************************************************************
990 	   * Change format:
991 	   *******************************************************************/
992 	   case CHANGEformatIN: {
993 	     if (!SelectFormat()) {
994 	       ItemWindow (DELETEiw, &IW);
995 	       return FALSE;
996 	     }
997 	     if (!BuildCDFmenu(CDFname,&IW)) {
998 	       ItemWindow (DELETEiw, &IW);
999 	       return FALSE;
1000 	     }
1001 	     ItemWindow (UPDATEiw, &IW, IW.itemN);
1002 	     break;
1003 	   }
1004 	   /*******************************************************************
1005 	   * Change encoding:
1006 	   *******************************************************************/
1007 	   case CHANGEencodingIN: {
1008 	     if (!SelectEncoding()) {
1009 	       ItemWindow (DELETEiw, &IW);
1010 	       return FALSE;
1011 	     }
1012 	     if (!BuildCDFmenu(CDFname,&IW)) {
1013 	       ItemWindow (DELETEiw, &IW);
1014 	       return FALSE;
1015 	     }
1016 	     ItemWindow (UPDATEiw, &IW, IW.itemN);
1017 	     break;
1018 	   }
1019 	   /*******************************************************************
1020 	   * Change majority:
1021 	   *******************************************************************/
1022 	   case CHANGEmajorityIN: {
1023 	     if (!SelectMajority()) {
1024 	       ItemWindow (DELETEiw, &IW);
1025 	       return FALSE;
1026 	     }
1027 	     if (!BuildCDFmenu(CDFname,&IW)) {
1028 	       ItemWindow (DELETEiw, &IW);
1029 	       return FALSE;
1030 	     }
1031 	     ItemWindow (UPDATEiw, &IW, IW.itemN);
1032 	     break;
1033 	   }
1034 	   /*******************************************************************
1035 	   * Select CDF compression:
1036 	   *******************************************************************/
1037 	   case CHANGEcompressionIN:
1038 	     if (!SelectCompression(FORCDF,12,NULL)) {
1039 	       ItemWindow (DELETEiw, &IW);
1040 	       return FALSE;
1041 	     }
1042 	     if (!BuildCDFmenu(CDFname,&IW)) {
1043 	       ItemWindow (DELETEiw, &IW);
1044 	       return FALSE;
1045 	     }
1046 	     ItemWindow (UPDATEiw, &IW, IW.itemN);
1047 	     break;
1048            /*******************************************************************
1049            * Change checksum:
1050            *******************************************************************/
1051            case CHANGEchecksumIN: {
1052              if (!SelectChecksum()) {
1053                ItemWindow (DELETEiw, &IW);
1054                return FALSE;
1055              }
1056              if (!BuildCDFmenu(CDFname,&IW)) {
1057                ItemWindow (DELETEiw, &IW);
1058                return FALSE;
1059              }
1060              ItemWindow (UPDATEiw, &IW, IW.itemN);
1061              break;
1062            }
1063 	 }
1064 	 break;
1065        }
1066        /***********************************************************************
1067        * Delete CDF.
1068        ***********************************************************************/
1069        case DELETECDFkey_EDIT:
1070 		 if (!browseOnly) {
1071 			char delim, question[DU_MAX_NAME_LEN+15+1];
1072 			delim = PickDelimiter (CDFname, strlen(CDFname));
1073 	   		sprintf (question, "Delete CDF %c%s%c ?", delim, CDFname, delim);
1074 	   		if (ConfirmWindow(12,80,question,NULL,FALSE,DELETECDFhelpID)) {
1075 	     	  status = CDFlib (DELETE_, CDF_,
1076 			  			       NULL_);
1077 	     	  if (ReportStatus(status,FALSE)) {
1078 				ItemWindow (DELETEiw, &IW);
1079 	       		*closed = TRUE;
1080 	       		return TRUE;
1081 	     	  }
1082 	     	  if (NoMoreAccess(NULL)) {
1083 	       		ItemWindow (DELETEiw, &IW);
1084 	       		return FALSE;
1085 	     	  }
1086 	   		}
1087 	 	  }
1088 	 	else
1089 	   	  ProblemWindow ("Deleting a CDF not allowed while browsing.", FALSE);
1090 	 	break;
1091        /***********************************************************************
1092        * zMode selection keys.
1093        ***********************************************************************/
1094        case zMODE0key_EDIT:
1095        case zMODE1key_EDIT:
1096        case zMODE2key_EDIT: {
1097 	 	 long zMode;
1098 	 	 switch (IW.key) {
1099 	   		case zMODE0key_EDIT: zMode = zMODEoff; break;
1100 	   		case zMODE1key_EDIT: zMode = zMODEon1; break;
1101 	   		case zMODE2key_EDIT: zMode = zMODEon2; break;
1102 	 	 }
1103 	 	 status = CDFlib (SELECT_, CDF_zMODE_, zMode,
1104 						  NULL_);
1105 	 	 if (!ReportStatus(status,FALSE)) {
1106 	   	   ItemWindow (DELETEiw, &IW);
1107 	   	   return FALSE;
1108 	 	 }
1109 	 	 if (!BuildCDFmenu(CDFname,&IW)) {
1110 	 	   ItemWindow (DELETEiw, &IW);
1111 	 	   return FALSE;
1112 	 	 }
1113 	 	 ItemWindow (UPDATEiw, &IW, IW.itemN);
1114 	 	 break;
1115        }
1116        /***********************************************************************
1117        * Display online help.
1118        ***********************************************************************/
1119        case HELPkey_FSI:
1120 		 OnlineHelpWindow (ilhFile, CDFhelpID);
1121 	 	 break;
1122        /***********************************************************************
1123        * Exit menu (closing CDF).
1124        ***********************************************************************/
1125        case EXITkey_FSI: {
1126 	 	 if (dumpStatistics) {
1127 	 	   vSTATS vStatsDotCDF, vStatsStage, vStatsCompress;
1128 	   	   char temp1[MAX_SCREENLINE_LEN+1],
1129 				temp2[MAX_SCREENLINE_LEN+1],
1130 				temp3[MAX_SCREENLINE_LEN+1];
1131 	   	   if (compressed) {
1132 	     	 MessageWindow (closingLines, NULL, LogicalFALSE);
1133 	    	 zzzzz (1.0);
1134 	  	   }
1135 	   	   status = CDFlib (CLOSE_, CDFwithSTATS_, &vStatsDotCDF,
1136 							&vStatsStage,
1137 							&vStatsCompress,
1138 						    NULL_);
1139 	   		if (compressed) MessageWindow (NULL);
1140 	   		*closed = TRUE;
1141 	   		if (!ReportStatus(status,FALSE)) {
1142 	     	  ItemWindow (DELETEiw, &IW);
1143 	     	  return FALSE;
1144 	   		}
1145 	   		ItemWindow (DELETEiw, &IW);
1146 	   		if (vStatsDotCDF.maxBuffers > 0) {
1147 	     	  BuildStatistics ("DotCDF file", &vStatsDotCDF,
1148 			  			       temp1, temp2, temp3);
1149 	     	  InfoWindow (temp1, temp2, temp3, TRUE, FALSE, 0);
1150 	   		}
1151 	   		if (vStatsStage.maxBuffers > 0) {
1152 	     	  BuildStatistics ("staging file", &vStatsStage,
1153 			  				    temp1, temp2, temp3);
1154 	     	  InfoWindow (temp1, temp2, temp3, TRUE, FALSE, 0);
1155 	   		}
1156 	   		if (vStatsCompress.maxBuffers > 0) {
1157 	    	  BuildStatistics ("compression scratch file", &vStatsCompress,
1158 			 				     temp1, temp2, temp3);
1159 	    	  InfoWindow (temp1, temp2, temp3, TRUE, FALSE, 0);
1160 	   		}
1161 	 	  }
1162 	 	  else {
1163 	   		if (compressed) {
1164 	     		MessageWindow (closingLines, NULL, LogicalFALSE);
1165 	     		zzzzz (1.0);
1166 	   		}
1167 	   		status = CDFlib (CLOSE_, CDF_,
1168 							 NULL_);
1169 	   		if (compressed) MessageWindow (NULL);
1170 	   		*closed = TRUE;
1171 	   		if (!ReportStatus(status,FALSE)) {
1172 	   		  ItemWindow (DELETEiw, &IW);
1173 	   		  return FALSE;
1174 	   		}
1175 	 		ItemWindow (DELETEiw, &IW);
1176 	 	  }
1177 	 	  return TRUE;
1178        }
1179      }
1180    }
1181 }
1182 
1183 /******************************************************************************
1184 * BuildCDFmenu.
1185 ******************************************************************************/
1186 
BuildCDFmenu(CDFname,IW)1187 Logical BuildCDFmenu (CDFname, IW)
1188 char *CDFname;
1189 struct ItemWindowStruct *IW;
1190 {
1191   CDFstatus status;
1192   long format, encoding, majority, checksum;
1193   long nAttrs, NgAttrs, NvAttrs, NrVars, NzVars;
1194   long version, release, increment;
1195   long cType, cParms[CDF_MAX_PARMS], cPct;
1196   int pad;
1197   /****************************************************************************
1198   * Encode label with name of CDF.
1199   ****************************************************************************/
1200   sprintf (IW->label, " CDF \"%s\" ", CDFname);
1201   /****************************************************************************
1202   * Inquire CDF.
1203   ****************************************************************************/
1204   status = CDFlib (GET_, CDF_FORMAT_, &format,
1205 			 CDF_ENCODING_, &encoding,
1206 			 CDF_MAJORITY_, &majority,
1207 			 CDF_NUMATTRS_, &nAttrs,
1208 			 CDF_NUMgATTRS_, &NgAttrs,
1209 			 CDF_NUMvATTRS_, &NvAttrs,
1210 			 CDF_NUMrVARS_, &NrVars,
1211 			 CDF_NUMzVARS_, &NzVars,
1212 			 CDF_VERSION_, &version,
1213 			 CDF_RELEASE_, &release,
1214 			 CDF_INCREMENT_, &increment,
1215 			 CDF_COMPRESSION_, &cType, cParms, &cPct,
1216 			 CDF_CHECKSUM_, &checksum,
1217 		   NULL_);
1218   if (!ReportStatus(status,FALSE)) return FALSE;
1219   /****************************************************************************
1220   * Encode first line of header.
1221   ****************************************************************************/
1222   sprintf (IW->hLines[0], "Format:   %s", FormatToken(format));
1223   pad = MAIN_MENU_1st_THIRD_LEN - strlen(IW->hLines[0]);
1224   if (pad > 0) CatNcharacters (IW->hLines[0], pad, (int) ' ');
1225   sprintf (EofS(IW->hLines[0]), "Attributes: %ld (%ldg/%ldv)",
1226 	   nAttrs, NgAttrs, NvAttrs);
1227   pad = MAIN_MENU_2nd_THIRD_LEN - strlen(IW->hLines[0]);
1228   if (pad > 0) CatNcharacters (IW->hLines[0], pad, (int) ' ');
1229   sprintf (EofS(IW->hLines[0]), "Compression: %s",
1230 	   CompressionToken(cType,cParms));
1231 #if 0
1232   if (cType != NO_COMPRESSION && cPct > 0) {
1233     sprintf (EofS(IW->hLines[0]), " (%ld%%)", cPct);
1234   }
1235 #endif
1236   /****************************************************************************
1237   * Encode second line of header.
1238   ****************************************************************************/
1239   sprintf (IW->hLines[1], "Majority: %s", MajorityToken(majority));
1240   pad = MAIN_MENU_1st_THIRD_LEN - strlen(IW->hLines[1]);
1241   if (pad > 0) CatNcharacters (IW->hLines[1], pad, (int) ' ');
1242   sprintf (EofS(IW->hLines[1]), "Variables:  %ld (%ldr/%ldz)",
1243 	   NrVars + NzVars, NrVars, NzVars);
1244   pad = MAIN_MENU_2nd_THIRD_LEN - strlen(IW->hLines[1]);
1245   if (pad > 0) CatNcharacters (IW->hLines[1], pad, (int) ' ');
1246   sprintf (EofS(IW->hLines[1]), "Encoding:    %s", EncodingToken(encoding));
1247   /****************************************************************************
1248   * Encode third line of header.
1249   ****************************************************************************/
1250   sprintf (IW->hLines[2], "Version:  %ld.%ld.%ld",
1251 	   version, release, increment);
1252   pad = MAIN_MENU_1st_THIRD_LEN - strlen(IW->hLines[2]);
1253   if (pad > 0) CatNcharacters (IW->hLines[2], pad, (int) ' ');
1254   sprintf (EofS(IW->hLines[2]), "Checksum:   %s", ChecksumToken(checksum));
1255   return TRUE;
1256 }
1257 
1258 /******************************************************************************
1259 * PromptForSpec.
1260 *     Prompt for the CDF(s) specification.  Returns TRUE if a valid CDF(s)
1261 * specification was entered; FALSE otherwise.
1262 ******************************************************************************/
1263 
PromptForSpec(CDFspec)1264 Logical PromptForSpec (CDFspec)
1265 char CDFspec[DU_MAX_PATH_LEN+1];
1266 {
1267   static char *header[] = {
1268     "Enter CDF(s) specification (without delimiters)...",
1269     "Syntax: <char1><char2>...<charN>",
1270 #if defined(vms)
1271     "Examples: RAIN2, RAIN*, [-.SAMPLES], USER5:[CDF1]IJ01A"
1272 #endif
1273 #if (defined(unix) && !defined(__CYGWIN__) && !defined(__MINGW32__)) || \
1274      defined(posixSHELL)
1275     "Examples: rain2, rain*, ../samples, ~/CDFs/ij01a"
1276 #endif
1277 #if defined(dos)
1278     "Examples: RAIN2, RAIN*, ..\\SAMPLES, B:\\CDF1\\IJ01A"
1279 #endif
1280 #if defined(win32) || defined(__CYGWIN__) || defined(__MINGW32__)
1281     "Examples: rain2, rain*, ..\\samples, b:\\cdf1\\ij01a"
1282 #endif
1283 #if defined(mac)
1284     "Examples: cacsst1, cac*, Boot:CDFs:, :samples"
1285 #endif
1286   };
1287 #if BROWSEaware
1288   AOSs1 (trailer, "Enter: ________  Exit: ________  Help: ________  More help: ________")
1289   static int exitChars[] = {
1290     ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, MOREHELPkey_EDIT, NUL
1291   };
1292 #else
1293   AOSs1 (trailer, "Enter: ________  Exit: ________  Help: ________")
1294   static int exitChars[] = { ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NUL };
1295 #endif
1296   static char value[DU_MAX_PATH_LEN+1];
1297   static struct PromptWindowStruct PW = {
1298     " Specification Prompt ", 5, 5, 70, 3, header, DU_MAX_PATH_LEN, value,
1299     1, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI,
1300     INSERTorOVERkey_FSI
1301   };
1302 #if BROWSEaware
1303   EncodeKeyDefinitions (1, trailer, ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI,
1304 			MOREHELPkey_EDIT);
1305 #else
1306   EncodeKeyDefinitions (1, trailer, ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI);
1307 #endif
1308   strcpyX (PW.value, CDFspec, DU_MAX_PATH_LEN);
1309   PromptWindow (NEWpw, &PW, (int) strlen(PW.value), LogicalTRUE);
1310   for (;;) {
1311      PromptWindow (READiw, &PW);
1312      switch (PW.key) {
1313        case ENTERkey_FSI:
1314 	 if (strlen(PW.value) > (size_t) 0) {
1315 	   strcpyX (CDFspec, PW.value, DU_MAX_PATH_LEN);
1316 	   PromptWindow (DELETEpw, &PW);
1317 	   return TRUE;
1318          }
1319 	 else
1320 	   ProblemWindow ("Illegal CDF(s) specification.", FALSE);
1321 	 break;
1322        case EXITkey_FSI:
1323 	 PromptWindow (DELETEpw, &PW);
1324 	 return FALSE;
1325        case HELPkey_FSI:
1326 	 OnlineHelpWindow (ilhFile, SPEChelpID);
1327 	 break;
1328 #if BROWSEaware
1329        case MOREHELPkey_EDIT:
1330 	 OnlineHelpWindow (ilhFile, MOREHELPhelpID);
1331 	 break;
1332 #endif
1333      }
1334   }
1335 }
1336 
1337 /******************************************************************************
1338 * EditQOPs.
1339 *    Returns TRUE if execution should continue.
1340 ******************************************************************************/
1341 
1342 #if defined(mac)
EditQOPs(argC,argV)1343 Logical EditQOPs (argC, argV)
1344 int *argC;
1345 char **argV[];
1346 {
1347   DialogPtr dialogP;
1348   DialogRecord dRecord;
1349   WindowPtr behind = (WindowPtr) -1;
1350   ControlHandle controlHs[MAXIMUMin+1];
1351   Rect iRect;
1352   short iType, i;
1353 #ifndef __MWERKS__
1354   short itemN;
1355 #else
1356   SInt16 itemN;
1357   ModalFilterUPP FilterDialogQOPfsiUPP;
1358   FileFilterUPP FilterForCDFsUPP;
1359   UserItemUPP OutlineDefaultButtonUPP;
1360 #endif
1361   static Logical browseOnly = DEFAULTbrowseEDIT;
1362   static Logical useFormat = DEFAULTformatEDIT;
1363   static Logical negToPos = DEFAULT_NEGtoPOSfp0;
1364   static Logical promptFor = DEFAULTpromptEDIT;
1365   static Logical reportInfos = REPORTinfosDEFAULT;
1366   static Logical reportWarns = REPORTwarningsDEFAULT;
1367   static Logical reportErrors = REPORTerrorsDEFAULT;
1368   static Logical dispStats = DEFAULTstatsEDIT;
1369   static Logical gWith = DEFAULTgWithEDIT;
1370   static Logical vWith = DEFAULTgWithEDIT;
1371   static int zMode = DEFAULTzModeEDIT;
1372   static Str255 cacheText = "\p";
1373   static Str255 CDFtext = "\p";
1374   /****************************************************************************
1375   * Create the dialog and get the control handles.
1376   ****************************************************************************/
1377   dialogP = GetNewDialog (QOPri, &dRecord, behind);
1378   for (itemN = 1; itemN <= MAXIMUMin; itemN++) {
1379      GetDItem (dialogP, itemN, &iType, (Handle *) &controlHs[itemN], &iRect);
1380   }
1381   /****************************************************************************
1382   * Set the control values.
1383   ****************************************************************************/
1384   SetIText ((Handle) controlHs[CDFTEXTin], CDFtext);
1385   SetIText ((Handle) controlHs[CACHEin], cacheText);
1386 
1387   if (browseOnly) SetCtlValue (controlHs[BROWSEin], 1);
1388   if (useFormat) SetCtlValue (controlHs[FORMATin], 1);
1389   if (negToPos) SetCtlValue (controlHs[NEGZin], 1);
1390   if (promptFor) SetCtlValue (controlHs[PROMPTin], 1);
1391   if (reportInfos) SetCtlValue (controlHs[INFOin], 1);
1392   if (reportWarns) SetCtlValue (controlHs[WARNin], 1);
1393   if (reportErrors) SetCtlValue (controlHs[ERRORin], 1);
1394   if (dispStats) SetCtlValue (controlHs[STATSin], 1);
1395   if (gWith) SetCtlValue (controlHs[gWITHin], 1);
1396   if (vWith) SetCtlValue (controlHs[vWITHin], 1);
1397 
1398   SetCtlValue (controlHs[ZMODEinBASE+zMode], 1);
1399 
1400 #ifndef __MWERKS__
1401   SetDItem (dialogP, (short) ODBin, (short) userItem,
1402 	    (Handle) OutlineDefaultButton, &iRect);
1403 #else
1404   OutlineDefaultButtonUPP = NewUserItemProc (OutlineDefaultButton);
1405   SetDItem (dialogP, (short) ODBin, (short) userItem,
1406 	    (Handle) OutlineDefaultButtonUPP, &iRect);
1407 #endif
1408   /****************************************************************************
1409   * Display the dialog and wait for user actions.
1410   ****************************************************************************/
1411   ShowWindow ((WindowPtr) dialogP);
1412   SetCursor (ARROW_CURSOR);
1413 #ifdef __MWERKS__
1414   FilterDialogQOPfsiUPP = NewModalFilterProc(FilterDialogQOPfsi);
1415 #endif
1416 
1417   for (;;) {
1418 #ifndef __MWERKS__
1419     ModalDialog (FilterDialogQOPfsi, &itemN);
1420 #else
1421     ModalDialog (FilterDialogQOPfsiUPP, &itemN);
1422 #endif
1423     switch (itemN) {
1424       /************************************************************************
1425       * Ok.
1426       ************************************************************************/
1427     case OKin: {
1428 		int n;
1429 		char tempS1[1+1];
1430 		/**********************************************************************
1431 		* Get the value of each control.
1432 		**********************************************************************/
1433 		GetIText ((Handle) controlHs[CDFTEXTin], CDFtext);
1434 		GetIText ((Handle) controlHs[CACHEin], cacheText);
1435 		browseOnly = GetCtlValue (controlHs[BROWSEin]);
1436 		useFormat = GetCtlValue (controlHs[FORMATin]);
1437 		negToPos = GetCtlValue (controlHs[NEGZin]);
1438 		promptFor = GetCtlValue (controlHs[PROMPTin]);
1439 		reportInfos = GetCtlValue (controlHs[INFOin]);
1440 		reportWarns = GetCtlValue (controlHs[WARNin]);
1441 		reportErrors = GetCtlValue (controlHs[ERRORin]);
1442 		dispStats = GetCtlValue (controlHs[STATSin]);
1443 		gWith = GetCtlValue (controlHs[gWITHin]);
1444 		vWith = GetCtlValue (controlHs[vWITHin]);
1445 		for (zMode = 0; zMode < 3; zMode++) {
1446 		   if (GetCtlValue(controlHs[ZMODEinBASE+zMode])) break;
1447 		}
1448 		/**********************************************************************
1449 		* Build argc/argv.
1450 		**********************************************************************/
1451 		*argC = 12 + BOO(NULpString(CDFtext),0,1) +
1452 			     BOO(NULpString(cacheText),0,2);
1453 		*argV = (char **) cdf_AllocateMemory (*argC * sizeof(char *), FatalError);
1454 		n = 0;
1455 		MAKEstrARGv (argV, n, pgmName)
1456 		MAKEbooARGv (argV, n, browseOnly, "-browse", "-nobrowse")
1457 		MAKEbooARGv (argV, n, useFormat, "-format", "-noformat")
1458 		MAKEbooARGv (argV, n, negToPos, "-neg2posfp0", "-noneg2posfp0")
1459 		MAKEbooARGv (argV, n, promptFor, "-prompt", "-noprompt")
1460 		MAKEbooARGv (argV, n, dispStats, "-statistics", "-nostatistics")
1461 		MAKEbooARGv (argV, n, gWith, "-gwithentries", "-nogwithentries")
1462 		MAKEbooARGv (argV, n, vWith, "-vwithentries", "-novwithentries")
1463 		MAKEstrARGv (argV, n, "-zmode")
1464 		sprintf (tempS1, "%d", zMode);
1465 		MAKEstrARGv (argV, n, tempS1)
1466 		MAKEstrARGv (argV, n, "-report")
1467 		MAKEstrARGv (argV, n, StatusCodeReportOptions(reportErrors,
1468 						      reportWarns,
1469 						      reportInfos))
1470 		if (!NULpString(cacheText)) {
1471 	  	  MAKEstrARGv (argV, n, "-cache")
1472 	  	  PtoCstr (cacheText);
1473 	  	  MAKEstrARGv (argV, n, (char *) cacheText)
1474 	  	  CtoPstr ((char *) cacheText);
1475 		}
1476 		if (!NULpString(CDFtext)) {
1477 		  PtoCstr (CDFtext);
1478 		  MAKEstrARGv (argV, n, (char *) CDFtext)
1479 		  CtoPstr ((char *) CDFtext);
1480 		}
1481 		/**********************************************************************
1482 		* Close the dialog and return.
1483 		**********************************************************************/
1484 #ifdef __MWERKS__
1485 		DisposeRoutineDescriptor(FilterDialogQOPfsiUPP);
1486 		DisposeRoutineDescriptor(OutlineDefaultButtonUPP);
1487 #endif
1488 		CloseDialog (dialogP);
1489 		return TRUE;
1490     }
1491     /************************************************************************
1492     * Help.
1493     ************************************************************************/
1494     case HELPin: {
1495 		int n;
1496 		*argC = 1;
1497 		*argV = (char **) cdf_AllocateMemory (*argC * sizeof(char *), FatalError);
1498 		n = 0;
1499 		MAKEstrARGv (argV, n, pgmName)
1500 #ifdef __MWERKS__
1501 		DisposeRoutineDescriptor(FilterDialogQOPfsiUPP);
1502 		DisposeRoutineDescriptor(OutlineDefaultButtonUPP);
1503 #endif
1504 		CloseDialog (dialogP);
1505 		return TRUE;
1506     }
1507     /************************************************************************
1508     * Cancel.
1509     ************************************************************************/
1510     case CANCELin:
1511 #ifdef __MWERKS__
1512     	DisposeRoutineDescriptor(FilterDialogQOPfsiUPP);
1513     	DisposeRoutineDescriptor(OutlineDefaultButtonUPP);
1514 #endif
1515 		CloseDialog (dialogP);
1516 		return FALSE;
1517     /************************************************************************
1518     * Select CDF specification (existing CDF).
1519     ************************************************************************/
1520     case CDFSELECTin: {
1521 		StandardFileReply CDFreply;
1522 		char CDFpath[DU_MAX_PATH_LEN+1];
1523 #ifndef __MWERKS__
1524 		StandardGetFile (FilterForCDFs, -1, NULL, &CDFreply);
1525 #else
1526 		FilterForCDFsUPP = NewFileFilterProc(FilterForCDFs);
1527 		StandardGetFile (FilterForCDFsUPP, -1, NULL, &CDFreply);
1528 		DisposeRoutineDescriptor(FilterForCDFsUPP);
1529 #endif
1530 		if (CDFreply.sfGood && !CDFreply.sfIsFolder && !CDFreply.sfIsVolume) {
1531 	  	  BuildMacPath (&CDFreply.sfFile, CDFpath, TRUE);
1532 	  	  CDFtext[0] = strlen (CDFpath);
1533 	  	  strcpyX ((char *) &CDFtext[1], CDFpath, 255);
1534 	  	  SetIText ((Handle) controlHs[CDFTEXTin], CDFtext);
1535 		}
1536 		break;
1537     }
1538     /************************************************************************
1539     * Select CDF specification (new CDF).
1540     * The cursor is set because `StandardPutFile' leaves the cursor as
1541     * an iBeam (instead of returning it to what it was).
1542     ************************************************************************/
1543     case CDFNEWin: {
1544 		StandardFileReply CDFreply;
1545 		char CDFpath[DU_MAX_PATH_LEN+1];
1546 		char prompt[] = "Enter CDF name:";
1547 		StandardPutFile (CtoPstr(prompt), CtoPstr(""), &CDFreply);
1548 		if (CDFreply.sfGood && !CDFreply.sfIsFolder && !CDFreply.sfIsVolume) {
1549 	  	  BuildMacPath (&CDFreply.sfFile, CDFpath, TRUE);
1550 	  	  CDFtext[0] = strlen (CDFpath);
1551 	  	  strcpyX ((char *) &CDFtext[1], CDFpath, 255);
1552 	  	  SetIText ((Handle) controlHs[CDFTEXTin], CDFtext);
1553 		}
1554 		SetCursor (&(qd.arrow));
1555 		break;
1556     }
1557     /************************************************************************
1558     * Check boxes.
1559     ************************************************************************/
1560     case BROWSEin:
1561     case FORMATin:
1562     case INFOin:
1563     case WARNin:
1564     case ERRORin:
1565     case NEGZin:
1566     case PROMPTin:
1567     case STATSin:
1568     case gWITHin:
1569     case vWITHin:
1570 		SetCtlValue (controlHs[itemN], BOO(GetCtlValue(controlHs[itemN]),0,1));
1571 		break;
1572     /************************************************************************
1573     * Radio buttons.
1574     ************************************************************************/
1575     case ZMODEinBASE+0:
1576     case ZMODEinBASE+1:
1577     case ZMODEinBASE+2:
1578 		for (i = 0; i < 3; i++) SetCtlValue (controlHs[ZMODEinBASE+i], 0);
1579 		  SetCtlValue (controlHs[itemN], 1);
1580 		break;
1581     	}
1582   }
1583 }
1584 #endif
1585