1 /*
2  * Grace - GRaphing, Advanced Computation and Exploration of data
3  *
4  * Home page: http://plasma-gate.weizmann.ac.il/Grace/
5  *
6  * Copyright (c) 1991-1995 Paul J Turner, Portland, OR
7  * Copyright (c) 1996-2009 Grace Development Team
8  *
9  * Maintained by Evgeny Stambulchik
10  *
11  *
12  *                           All Rights Reserved
13  *
14  *    This program is free software; you can redistribute it and/or modify
15  *    it under the terms of the GNU General Public License as published by
16  *    the Free Software Foundation; either version 2 of the License, or
17  *    (at your option) any later version.
18  *
19  *    This program is distributed in the hope that it will be useful,
20  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
21  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  *    GNU General Public License for more details.
23  *
24  *    You should have received a copy of the GNU General Public License
25  *    along with this program; if not, write to the Free Software
26  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27  */
28 
29 #include <config.h>
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <string.h>
35 #ifdef HAVE_FCNTL_H
36 #  include <fcntl.h>
37 #endif
38 
39 /* for globals.h */
40 #define MAIN
41 
42 #include "globals.h"
43 
44 #include "utils.h"
45 #include "files.h"
46 #include "ssdata.h"
47 
48 #include "graphs.h"
49 #include "graphutils.h"
50 #include "plotone.h"
51 
52 #include "device.h"
53 #include "devlist.h"
54 #ifndef NONE_GUI
55 #  include "x11drv.h"
56 #endif
57 #include "parser.h"
58 #include "protos.h"
59 
60 
61 extern char batchfile[];
62 extern char print_file[];
63 extern int install_cmap;
64 
65 extern Input_buffer *ib_tbl;
66 extern int ib_tblsize;
67 
68 static void usage(FILE *stream, char *progname);
69 static void VersionInfo(void);
70 
71 int inpipe = FALSE;		/* if xmgrace is to participate in a pipe */
72 
73 #if defined(DEBUG)
74     extern int yydebug;
75 #endif
76 
main(int argc,char * argv[])77 int main(int argc, char *argv[])
78 {
79     char *s;
80     int i, j;
81     int gno;
82     int fd;
83     world w;
84     view v;
85     int cur_graph;	        /* default (current) graph */
86     int loadlegend = FALSE;	/* legend on and load file names */
87     int gracebat;		/* if executed as 'gracebat' then TRUE */
88     int cli = FALSE;            /* command line interface only */
89     int remove_flag = FALSE;	/* remove file after read */
90     int noprint = FALSE;	/* if gracebat, then don't print if true */
91     int sigcatch = TRUE;	/* we handle signals ourselves */
92 
93     char fd_name[GR_MAXPATHLEN];
94 
95     int wpp, hpp;
96 
97     /*
98      * set version
99      */
100     reset_project_version();
101     /*
102      * grace home directory
103      */
104     if ((s = getenv("GRACE_HOME")) != NULL) {
105 	set_grace_home(s);
106     }
107 
108     /* define the user's name */
109     init_username();
110 
111     /* define the user's home dir */
112     init_userhome();
113 
114     /* set the starting directory */
115     set_workingdir(NULL);
116 
117     /*
118      * print command
119      */
120     if ((s = getenv("GRACE_PRINT_CMD")) != NULL) {
121 	set_print_cmd(s);
122     }
123 
124     /* if no print command defined, print to file by default */
125     s = get_print_cmd();
126     if (s == NULL || s[0] == '\0') {
127         set_ptofile(TRUE);
128     } else {
129         set_ptofile(FALSE);
130     }
131 
132     /*
133      * editor
134      */
135     if ((s = getenv("GRACE_EDITOR")) != NULL) {
136 	set_editor(s);
137     }
138 
139     /*
140      * check for changed help file viewer command
141      */
142     if ((s = getenv("GRACE_HELPVIEWER")) != NULL) {
143 	set_help_viewer(s);
144     }
145 
146     /* initialize plots, strings, graphs */
147     set_program_defaults();
148 
149     /* initialize the nonl-fit parameters */
150     initialize_nonl();
151 
152     /* initialize the parser symbol table */
153     init_symtab();
154 
155     /* initialize the rng */
156     srand48(100L);
157 
158     /* initialize T1lib */
159     if (init_t1() != RETURN_SUCCESS) {
160         errmsg("--> Broken or incomplete installation - read the FAQ!");
161 	exit (1);
162     }
163 
164     /* initialize colormap data */
165     initialize_cmap();
166 
167     /*
168      * if program name is gracebat* then don't initialize the X toolkit
169      */
170     s = mybasename(argv[0]);
171 
172     if (strstr(s, "gracebat") == s) {
173 	gracebat = TRUE;
174     } else {
175 	gracebat = FALSE;
176         if (strstr(s, "grace") == s) {
177             cli = TRUE;
178         } else {
179 #ifndef NONE_GUI
180             cli = FALSE;
181             if (initialize_gui(&argc, argv) != RETURN_SUCCESS) {
182 	        errmsg("Failed initializing GUI, exiting");
183                 exit(1);
184             }
185 #endif
186         }
187     }
188 
189     /* initialize devices */
190 #ifndef NONE_GUI
191     if (cli == TRUE || gracebat == TRUE) {
192         tdevice = register_dummy_drv();
193     } else {
194         tdevice = register_x11_drv();
195     }
196 #else
197     tdevice = register_dummy_drv();
198 #endif
199     select_device(tdevice);
200 
201     hdevice = register_ps_drv();
202     register_eps_drv();
203 
204 #ifdef HAVE_LIBPDF
205     register_pdf_drv();
206 #endif
207     register_mif_drv();
208     register_svg_drv();
209     register_pnm_drv();
210 #ifdef HAVE_LIBJPEG
211     register_jpg_drv();
212 #endif
213 #ifdef HAVE_LIBPNG
214     register_png_drv();
215 #endif
216 
217     register_mf_drv();
218 
219     /* check whether locale is correctly set */
220     if (init_locale() != RETURN_SUCCESS) {
221         errmsg("Invalid or unsupported locale");
222     }
223     /* default is POSIX */
224     set_locale_num(FALSE);
225 
226     /* load startup file */
227     getparms("gracerc");
228 
229     /* load default template */
230     new_project(NULL);
231 
232     cur_graph = get_cg();
233 
234     if (argc >= 2) {
235 	for (i = 1; i < argc; i++) {
236 	    if (argv[i][0] == '-' && argv[i][1] != '\0') {
237 		if (argmatch(argv[i], "-version", 2)) {
238                     VersionInfo();
239 		    exit(0);
240 		}
241 #if defined(DEBUG)
242 		if (argmatch(argv[i], "-debug", 6)) {
243 		    i++;
244 		    if (i == argc) {
245 			fprintf(stderr, "Missing argument for debug flag\n");
246 			usage(stderr, argv[0]);
247 		    } else {
248 		    	set_debuglevel(atoi(argv[i]));
249 		    	if (get_debuglevel() == 4) {
250 			    /* turn on debugging in pars.y */
251 			    yydebug = TRUE;
252 		    	}
253 		    }
254 		} else
255 #endif
256 		       if (argmatch(argv[i], "-nosigcatch", 6)) {
257 		    sigcatch = FALSE;
258 		} else if (argmatch(argv[i], "-autoscale", 2)) {
259 		    i++;
260 		    if (i == argc) {
261 			errmsg("Missing argument for autoscale flag");
262 			usage(stderr, argv[0]);
263 		    } else {
264 			if (!strcmp("x", argv[i])) {
265 			    autoscale_onread = AUTOSCALE_X;
266 			} else if (!strcmp("y", argv[i])) {
267 			    autoscale_onread = AUTOSCALE_Y;
268 			} else if (!strcmp("xy", argv[i])) {
269 			    autoscale_onread = AUTOSCALE_XY;
270 			} else if (!strcmp("none", argv[i])) {
271 			    autoscale_onread = AUTOSCALE_NONE;
272 			} else {
273 			    errmsg("Improper argument for autoscale flag");
274 			    usage(stderr, argv[0]);
275 			}
276 		    }
277 		} else if (argmatch(argv[i], "-batch", 2)) {
278 		    i++;
279 		    if (i == argc) {
280 			fprintf(stderr, "Missing argument for batch file\n");
281 			usage(stderr, argv[0]);
282 		    } else {
283 			strcpy(batchfile, argv[i]);
284 		    }
285 		} else if (argmatch(argv[i], "-datehint", 5)) {
286 		    i++;
287 		    if (i == argc) {
288 			errmsg("Missing argument for datehint flag");
289 			usage(stderr, argv[0]);
290 		    } else {
291 			if (!strcmp("iso", argv[i])) {
292 			    set_date_hint(FMT_iso);
293 			} else if (!strcmp("european", argv[i])) {
294 			    set_date_hint(FMT_european);
295 			} else if (!strcmp("us", argv[i])) {
296 			    set_date_hint(FMT_us);
297 			} else if (!strcmp("nohint", argv[i])) {
298 			    set_date_hint(FMT_nohint);
299 			} else {
300 			    errmsg("Improper argument for datehint flag");
301 			    usage(stderr, argv[0]);
302 			}
303 		    }
304 		} else if (argmatch(argv[i], "-pipe", 5)) {
305 		    inpipe = TRUE;
306 		} else if (argmatch(argv[i], "-noprint", 8)) {
307 		    noprint = TRUE;
308 		} else if (argmatch(argv[i], "-dpipe", 6)) {
309 		    i++;
310 		    if (i == argc) {
311 			fprintf(stderr, "Missing argument for descriptor pipe\n");
312 			usage(stderr, argv[0]);
313 		    } else {
314                         fd = atoi(argv[i]);
315                         sprintf(fd_name, "pipe<%d>", fd);
316                         if (register_real_time_input(fd, fd_name, FALSE) !=
317                             RETURN_SUCCESS) {
318                             exit(1);
319                         }
320 		    }
321 		} else if (argmatch(argv[i], "-npipe", 6)) {
322 		    i++;
323 		    if (i == argc) {
324 			fprintf(stderr, "Missing argument for named pipe\n");
325 			usage(stderr, argv[0]);
326 		    } else {
327                         fd = open(argv[i], O_RDONLY | O_NONBLOCK);
328                         if (fd < 0) {
329                             fprintf(stderr, "Can't open fifo\n");
330                         } else {
331                             if (register_real_time_input(fd, argv[i], TRUE) !=
332                                 RETURN_SUCCESS) {
333                                 exit(1);
334                             }
335                         }
336 		    }
337 #ifdef HAVE_NETCDF
338 		} else if (argmatch(argv[i], "-netcdf", 7) || argmatch(argv[i], "-hdf", 4)) {
339 		    i++;
340 		    if (i == argc) {
341 			fprintf(stderr, "Missing argument for netcdf file\n");
342 			usage(stderr, argv[0]);
343 		    } else {
344 			strcpy(netcdf_name, argv[i]);
345 		    }
346 		} else if (argmatch(argv[i], "-netcdfxy", 9) || argmatch(argv[i], "-hdfxy", 6)) {
347 		    i++;
348 		    if (i == argc) {
349 			fprintf(stderr, "Missing argument for netcdf X variable name\n");
350 			usage(stderr, argv[0]);
351 		    } else {
352 			strcpy(xvar_name, argv[i]);
353 		    }
354 		    i++;
355 		    if (i == argc) {
356 			fprintf(stderr, "Missing argument for netcdf Y variable name\n");
357 			usage(stderr, argv[0]);
358 		    } else {
359 			strcpy(yvar_name, argv[i]);
360 		    }
361 		    if (strcmp(xvar_name, "null")) {
362 			readnetcdf(cur_graph, -1, netcdf_name, xvar_name, yvar_name, -1, -1, 1);
363 		    } else {
364 			readnetcdf(cur_graph, -1, netcdf_name, NULL, yvar_name, -1, -1, 1);
365 		    }
366 #endif				/* HAVE_NETCDF */
367 		} else if (argmatch(argv[i], "-timer", 6)) {
368 		    i++;
369 		    if (i == argc) {
370 			fprintf(stderr, "Missing argument for time delay\n");
371 			usage(stderr, argv[0]);
372 		    } else {
373 			timer_delay = atoi(argv[i]);
374 		    }
375 #ifndef NONE_GUI
376 		} else if (argmatch(argv[i], "-install", 7)) {
377 		    install_cmap = CMAP_INSTALL_ALWAYS;
378 		} else if (argmatch(argv[i], "-noinstall", 9)) {
379 		    install_cmap = CMAP_INSTALL_NEVER;
380 		} else if (argmatch(argv[i], "-barebones", 9)) {
381 		    set_barebones( TRUE );
382 #endif
383 		} else if (argmatch(argv[i], "-timestamp", 10)) {
384 		    timestamp.active = TRUE;
385 		} else if (argmatch(argv[i], "-remove", 7)) {
386 		    remove_flag = TRUE;
387 		} else if (argmatch(argv[i], "-fixed", 5)) {
388 		    i++;
389 		    if (i == argc) {
390 			fprintf(stderr, "Missing argument for fixed canvas width\n");
391 			usage(stderr, argv[0]);
392 		    } else {
393 		        if (i == argc - 1) {
394 			    fprintf(stderr, "Missing argument for fixed canvas height\n");
395 			    usage(stderr, argv[0]);
396 		        } else {
397                             wpp = atoi(argv[i]);
398 		    	    i++;
399 		    	    hpp = atoi(argv[i]);
400                             set_page_dimensions(wpp, hpp, FALSE);
401 #ifndef NONE_GUI
402 		    	    set_pagelayout(PAGE_FIXED);
403 #endif
404 			}
405 		    }
406 #ifndef NONE_GUI
407 		} else if (argmatch(argv[i], "-free", 5)) {
408 		    set_pagelayout(PAGE_FREE);
409 #endif
410 		} else if (argmatch(argv[i], "-noask", 5)) {
411 		    noask = TRUE;
412 #ifndef NONE_GUI
413 		} else if (argmatch(argv[i], "-mono", 5)) {
414 		    monomode = TRUE;
415 #endif
416 		} else if (argmatch(argv[i], "-hdevice", 5)) {
417 		    i++;
418 		    if (i == argc) {
419 			fprintf(stderr, "Missing argument for hardcopy device select flag\n");
420 			usage(stderr, argv[0]);
421 		    } else {
422 		        if (set_printer_by_name(argv[i]) != RETURN_SUCCESS) {
423                             errmsg("Unknown or unsupported device");
424                             exit(1);
425                         }
426                     }
427 		} else if (argmatch(argv[i], "-log", 2)) {
428 		    i++;
429 		    if (i == argc) {
430 			fprintf(stderr, "Missing argument for log plots flag\n");
431 			usage(stderr, argv[0]);
432 		    }
433 		    if (!strcmp("x", argv[i])) {
434 			set_graph_xscale(cur_graph, SCALE_LOG);
435 		    } else if (!strcmp("y", argv[i])) {
436 			set_graph_yscale(cur_graph, SCALE_LOG);
437 		    } else if (!strcmp("xy", argv[i])) {
438 			set_graph_xscale(cur_graph, SCALE_LOG);
439 			set_graph_yscale(cur_graph, SCALE_LOG);
440 		    } else {
441 			fprintf(stderr, "%s: Improper argument for -l flag; should be one of 'x', 'y', 'xy'\n", argv[0]);
442 		    }
443 		} else if (argmatch(argv[i], "-printfile", 6)) {
444 		    i++;
445 		    if (i == argc) {
446 			fprintf(stderr, "Missing file name for printing\n");
447 			usage(stderr, argv[0]);
448 		    } else {
449 			set_ptofile(TRUE);
450                         strcpy(print_file, argv[i]);
451 		    }
452 		} else if (argmatch(argv[i], "-hardcopy", 6)) {
453 		    gracebat = TRUE;
454 		} else if (argmatch(argv[i], "-pexec", 6)) {
455 		    i++;
456 		    if (i == argc) {
457 			fprintf(stderr, "Missing argument for exec\n");
458 			usage(stderr, argv[0]);
459 		    } else {
460 			scanner(argv[i]);
461 		    }
462 		} else if (argmatch(argv[i], "-graph", 6)) {
463 		    i++;
464 		    if (i == argc) {
465 			fprintf(stderr, "Missing parameter for graph select\n");
466 			usage(stderr, argv[0]);
467 		    } else {
468 			sscanf(argv[i], "%d", &gno);
469 			if (set_graph_active(gno) == RETURN_SUCCESS) {
470 			    cur_graph = gno;
471                             select_graph(gno);
472 			} else {
473 			    fprintf(stderr, "Error activating graph %d\n", gno);
474 			}
475 		    }
476 		} else if (argmatch(argv[i], "-block", 6)) {
477 		    i++;
478 		    if (i == argc) {
479 			fprintf(stderr, "Missing filename for block data\n");
480 			usage(stderr, argv[0]);
481 		    } else {
482 			getdata(cur_graph, argv[i], cursource, LOAD_BLOCK);
483 		    }
484 		} else if (argmatch(argv[i], "-bxy", 4)) {
485 		    i++;
486 		    if (i == argc) {
487 			fprintf(stderr, "Missing parameter for block data set creation\n");
488 			usage(stderr, argv[0]);
489 		    } else {
490                         int nc, *cols, scol;
491                         if (field_string_to_cols(argv[i], &nc, &cols, &scol) !=
492                             RETURN_SUCCESS) {
493                             errmsg("Erroneous field specifications");
494                             return 1;
495                         }
496 		        create_set_fromblock(cur_graph, NEW_SET,
497                             curtype, nc, cols, scol, autoscale_onread);
498                         xfree(cols);
499                     }
500 		} else if (argmatch(argv[i], "-nxy", 4)) {
501 		    i++;
502 		    if (i == argc) {
503 			fprintf(stderr, "Missing filename for nxy data\n");
504 			usage(stderr, argv[0]);
505 		    } else {
506 			getdata(cur_graph, argv[i], cursource, LOAD_NXY);
507 		    }
508 		} else if (argmatch(argv[i], "-type", 2) ||
509                            argmatch(argv[i], "-settype", 8)) {
510 		    /* set types */
511 		    i++;
512                     curtype = get_settype_by_name(argv[i]);
513                     if (curtype == -1) {
514 			fprintf(stderr, "%s: Unknown set type '%s'\n", argv[0], argv[i]);
515 			usage(stderr, argv[0]);
516 		    }
517 		} else if (argmatch(argv[i], "-graphtype", 7)) {
518 		    i++;
519 		    if (i == argc) {
520 			fprintf(stderr, "Missing argument for graph type\n");
521 		    } else {
522 			if (!strcmp("xy", argv[i])) {
523 			    set_graph_type(cur_graph, GRAPH_XY);
524 			} else
525                         if (!strcmp("polar", argv[i])) {
526 			    set_graph_type(cur_graph, GRAPH_POLAR);
527 			} else
528                         if (!strcmp("bar", argv[i]) || !strcmp("chart", argv[i])) {
529 			    set_graph_type(cur_graph, GRAPH_CHART);
530 			} else
531                         if (!strcmp("smith", argv[i])) {
532 			    set_graph_type(cur_graph, GRAPH_SMITH);
533 			} else
534                         if (!strcmp("fixed", argv[i])) {
535 			    set_graph_type(cur_graph, GRAPH_FIXED);
536 			} else
537                         if (!strcmp("pie", argv[i])) {
538 			    set_graph_type(cur_graph, GRAPH_PIE);
539 			} else {
540 			    fprintf(stderr, "%s: Improper argument for -graphtype\n", argv[0]);
541 			    usage(stderr, argv[0]);
542 			}
543 		    }
544 		} else if (argmatch(argv[i], "-legend", 4)) {
545 		    i++;
546 		    if (i == argc) {
547 			fprintf(stderr, "Missing argument for -legend\n");
548 			usage(stderr, argv[0]);
549 		    } else {
550 			if (!strcmp("load", argv[i])) {
551 			    loadlegend = TRUE;
552 			    set_graph_legend_active(cur_graph, TRUE);
553 			} else {
554 			    fprintf(stderr, "Improper argument for -legend\n");
555 			    usage(stderr, argv[0]);
556 			}
557 		    }
558 		} else if (argmatch(argv[i], "-rvideo", 7)) {
559 		    reverse_video();
560 		} else if (argmatch(argv[i], "-param", 2)) {
561 		    i++;
562 		    if (i == argc) {
563 			fprintf(stderr, "Missing parameter file name\n");
564 			usage(stderr, argv[0]);
565 		    } else {
566 			if (!getparms(argv[i])) {
567 			    fprintf(stderr, "Unable to read parameter file %s\n", argv[i]);
568 			}
569 		    }
570 		} else if (argmatch(argv[i], "-results", 2)) {
571 		    i++;
572 		    if (i == argc) {
573 			fprintf(stderr, "Missing results file name\n");
574 			usage(stderr, argv[0]);
575 		    } else {
576                         /*  open resfile if -results option given */
577 		        if ((resfp = grace_openw(argv[i])) == NULL) {
578 		            exit(1);
579 		        }
580 			setvbuf(resfp, NULL, _IOLBF, 0);
581 		    }
582 		} else if (argmatch(argv[i], "-saveall", 8)) {
583 		    i++;
584 		    if (i == argc) {
585 			fprintf(stderr, "Missing save file name\n");
586 			usage(stderr, argv[0]);
587 		    } else {
588 			save_project(argv[i]);
589 		    }
590 		} else if (argmatch(argv[i], "-wd", 3)) {
591 		    i++;
592 		    if (i == argc) {
593 			fprintf(stderr, "Missing parameters for working directory\n");
594 			usage(stderr, argv[0]);
595 		    } else {
596 			if (set_workingdir(argv[i]) != RETURN_SUCCESS) {
597 			    fprintf(stderr, "Can't change to directory %s, fatal error", argv[i]);
598 			    exit(1);
599 			}
600 		    }
601 		} else if (argmatch(argv[i], "-source", 2)) {
602 		    i++;
603 		    if (i == argc) {
604 			fprintf(stderr, "Missing argument for data source parameter\n");
605 			usage(stderr, argv[0]);
606 		    }
607 		    if (argmatch(argv[i], "pipe", 4)) {
608 			cursource = SOURCE_PIPE;
609 		    } else if (argmatch(argv[i], "disk", 4)) {
610 			cursource = SOURCE_DISK;
611 		    }
612 		} else if (argmatch(argv[i], "-viewport", 2)) {
613 		    i++;
614 		    if (i > argc - 4) {
615 			fprintf(stderr, "Missing parameter(s) for viewport setting\n");
616 			usage(stderr, argv[0]);
617 		    } else {
618 			v.xv1 = atof(argv[i++]);
619 			v.yv1 = atof(argv[i++]);
620 			v.xv2 = atof(argv[i++]);
621 			v.yv2 = atof(argv[i]);
622 			set_graph_viewport(cur_graph, v);
623 		    }
624 		} else if (argmatch(argv[i], "-world", 2)) {
625 		    i++;
626 		    if (i > argc - 4) {
627 			fprintf(stderr, "Missing parameter(s) for world setting\n");
628 			usage(stderr, argv[0]);
629 		    } else {
630 			w.xg1 = atof(argv[i++]);
631 			w.yg1 = atof(argv[i++]);
632 			w.xg2 = atof(argv[i++]);
633 			w.yg2 = atof(argv[i]);
634                         set_graph_world(cur_graph, w);
635 		    }
636 		} else if (argmatch(argv[i], "-seed", 5)) {
637 		    i++;
638 		    if (i == argc) {
639 			fprintf(stderr, "Missing seed for srand48()\n");
640 			usage(stderr, argv[0]);
641 		    } else {
642 			srand48(atol(argv[i]));	/* note atol() */
643 		    }
644 		} else if (argmatch(argv[i], "-maxpath", 8)) {
645 		    i++;
646 		    if (i == argc) {
647 			fprintf(stderr, "Missing argument for max drawing path\n");
648 			usage(stderr, argv[0]);
649 		    } else {
650 			set_max_path_limit(atoi(argv[i]));
651 		    }
652 		} else if (argmatch(argv[i], "-safe", 5)) {
653 		    safe_mode = TRUE;
654 		} else if (argmatch(argv[i], "-nosafe", 7)) {
655 		    safe_mode = FALSE;
656 		} else if (argmatch(argv[i], "-help", 2)) {
657 		    usage(stdout, argv[0]);
658 		} else if (argmatch(argv[i], "-usage", 5)) {
659 		    usage(stdout, argv[0]);
660 		} else {
661 		    fprintf(stderr, "No option %s\n", argv[i]);
662 		    usage(stderr, argv[0]);
663 		}
664 	    } else {
665 		if (i != argc) {
666 		    if (getdata(cur_graph, argv[i], cursource, LOAD_SINGLE) ==
667                                                         RETURN_SUCCESS) {
668 			set_docname(argv[i]);
669 			if (remove_flag) {
670 			    unlink(argv[i]);
671 			}
672 			clear_dirtystate();
673 		    }
674 		}		/* end if */
675 	    }			/* end else */
676 	}			/* end for */
677     }				/* end if */
678 
679 
680     /*
681      * Process events.
682      */
683     if (sigcatch == TRUE) {
684         installSignal();
685     }
686 
687 /*
688  * load legend
689  */
690     if (loadlegend) {
691 	for (i = 0; i < number_of_graphs(); i++) {
692 	    if (is_graph_active(i)) {
693 		for (j = 0; j < number_of_sets(i); j++) {
694 		    load_comments_to_legend(i, j);
695 		}
696 	    }
697 	}
698     }
699 
700 /*
701  * if -hardcopy on command line or executed as gracebat,
702  * just plot the graph and quit
703  */
704     if (gracebat == TRUE) {
705 	if (hdevice == 0) {
706 	    errmsg("Terminal device can't be used for batch plotting");
707 	    exit(1);
708 	}
709 	if (inpipe == TRUE) {
710             getdata(cur_graph, "stdin", SOURCE_DISK, LOAD_SINGLE);
711 	    inpipe = FALSE;
712 	}
713 	if (batchfile[0]) {
714 	    getparms(batchfile);
715 	}
716         while (real_time_under_monitoring()) {
717             monitor_input(ib_tbl, ib_tblsize, 0);
718         }
719 	if (!noprint) {
720 	    do_hardcopy();
721 	}
722 
723 	bailout();
724     } else {
725 /*
726  * go main loop
727  */
728 #ifndef NONE_GUI
729         if (cli == TRUE) {
730             cli_loop();
731         } else {
732             startup_gui();
733         }
734 #else
735         cli_loop();
736 #endif
737     }
738     /* never reaches */
739     exit(0);
740 }
741 
742 /*
743  * command interface loop
744  */
cli_loop(void)745 void cli_loop(void)
746 {
747     Input_buffer *ib_stdin;
748     int previous = -1;
749 
750     if (inpipe == TRUE) {
751         getdata(get_cg(), "stdin", SOURCE_DISK, LOAD_SINGLE);
752         inpipe = FALSE;
753     }
754     if (batchfile[0]) {
755         getparms(batchfile);
756     }
757 
758     if (register_real_time_input(STDIN_FILENO, "stdin", 0)
759         != RETURN_SUCCESS) {
760         exit(1);
761     }
762     for (ib_stdin = ib_tbl; ib_stdin->fd != STDIN_FILENO; ib_stdin++) {
763         ;
764     }
765 
766     while (ib_stdin->fd == STDIN_FILENO) {
767         /* the standard input is still under monitoring */
768         if (ib_stdin->lineno != previous) {
769             printf("grace:%d> ", ib_stdin->lineno + 1);
770             fflush(stdout);
771             previous = ib_stdin->lineno;
772         }
773         monitor_input(ib_tbl, ib_tblsize, 0);
774     }
775 
776 }
777 
usage(FILE * stream,char * progname)778 static void usage(FILE *stream, char *progname)
779 {
780 /* We use alphabetial order */
781 
782     fprintf(stream, "Usage of %s command line arguments: \n", progname);
783 
784     fprintf(stream, "-autoscale [x|y|xy|none]              Set autoscale type\n");
785 #ifndef NONE_GUI
786     fprintf(stream, "-barebones                            Turn off all toolbars\n");
787 #endif
788     fprintf(stream, "-batch     [batch_file]               Execute batch_file on start up\n");
789     fprintf(stream, "-block     [block_data]               Assume data file is block data\n");
790     fprintf(stream, "-bxy       [x:y:etc.]                 Form a set from the current block data set\n");
791     fprintf(stream, "                                        using the current set type from columns\n");
792     fprintf(stream, "                                        given in the argument\n");
793     fprintf(stream, "-datehint  [iso|european|us\n");
794     fprintf(stream, "            |days|seconds|nohint]     Set the hint for dates analysis\n");
795     fprintf(stream, "                                        (it is only a hint for the parser)\n");
796 #if defined(DEBUG)
797     fprintf(stream, "-debug     [debug_level]              Set debugging options\n");
798 #endif
799     fprintf(stream, "-dpipe     [descriptor]               Read data from descriptor on startup\n");
800     fprintf(stream, "-fixed     [width] [height]           Set canvas size fixed to width*height\n");
801 #ifndef NONE_GUI
802     fprintf(stream, "-free                                 Use free page layout\n");
803 #endif
804     fprintf(stream, "-graph     [graph_number]             Set the current graph number\n");
805     fprintf(stream, "-graphtype [xy|chart|fixed|polar|pie] Set the type of the current graph\n");
806     fprintf(stream, "-hardcopy                             No interactive session, just print and\n");
807     fprintf(stream, "                                        quit\n");
808     fprintf(stream, "-hdevice   [hardcopy_device_name]     Set default hardcopy device\n");
809 #ifndef NONE_GUI
810     fprintf(stream, "-install                              Install private colormap\n");
811 #endif
812     fprintf(stream, "-legend    [load]                     Turn the graph legend on\n");
813     fprintf(stream, "-log       [x|y|xy]                   Set the axis scaling of the current graph\n");
814     fprintf(stream, "                                        to logarithmic\n");
815     fprintf(stream, "-maxpath   [length]                   Set the maximal drawing path length\n");
816 #ifndef NONE_GUI
817     fprintf(stream, "-mono                                 Run Grace in monochrome mode (affects\n");
818     fprintf(stream, "                                        the display only)\n");
819 #endif
820 #ifdef HAVE_NETCDF
821     fprintf(stream, "-netcdf    [netcdf file]              Assume data file is in netCDF format\n");
822     fprintf(stream, "-netcdfxy  [X var name] [Y var name]  If -netcdf was used previously, read from\n");
823     fprintf(stream, "                                        the netCDF file 'X var name' and 'Y\n");
824     fprintf(stream, "                                        var name' and create a set. If 'X var\n");
825     fprintf(stream, "                                        name' is \"null\" then load the\n");
826     fprintf(stream, "                                        index of Y to X\n");
827 #endif
828     fprintf(stream, "-noask                                Assume the answer is yes to all requests -\n");
829     fprintf(stream, "                                        if the operation would overwrite a file,\n");
830     fprintf(stream, "                                        grace will do so without prompting\n");
831 #ifndef NONE_GUI
832     fprintf(stream, "-noinstall                            Don't use private colormap\n");
833 #endif
834     fprintf(stream, "-noprint                              In batch mode, do not print\n");
835     fprintf(stream, "-nosafe                               Disable safe mode\n");
836     fprintf(stream, "-nosigcatch                           Don't catch signals\n");
837     fprintf(stream, "-npipe     [file]                     Read data from named pipe on startup\n");
838     fprintf(stream, "-nxy       [nxy_file]                 Assume data file is in X Y1 Y2 Y3 ...\n");
839     fprintf(stream, "                                        format\n");
840     fprintf(stream, "-param     [parameter_file]           Load parameters from parameter_file to the\n");
841     fprintf(stream, "                                        current graph\n");
842     fprintf(stream, "-pexec     [parameter_string]         Interpret string as a parameter setting\n");
843     fprintf(stream, "-pipe                                 Read data from stdin on startup\n");
844     fprintf(stream, "-printfile [file for hardcopy output] Save print output to file \n");
845     fprintf(stream, "-remove                               Remove data file after read\n");
846     fprintf(stream, "-results   [results_file]             Write results of some data manipulations\n");
847     fprintf(stream, "                                        to results_file\n");
848     fprintf(stream, "-rvideo                               Exchange the color indices for black and\n");
849     fprintf(stream, "                                        white\n");
850     fprintf(stream, "-safe                                 Safe mode (default)\n");
851     fprintf(stream, "-saveall   [save_file]                Save all to save_file\n");
852     fprintf(stream, "-seed      [seed_value]               Integer seed for random number generator\n");
853     fprintf(stream, "-source    [disk|pipe]                Source type of next data file\n");
854     fprintf(stream, "-timer     [delay]                    Set allowed time slice for real time\n");
855     fprintf(stream, "                                        inputs to delay ms\n");
856     fprintf(stream, "-timestamp                            Add timestamp to plot\n");
857     fprintf(stream, "-settype   [xy|xydx|...]              Set the type of the next data file\n");
858     fprintf(stream, "-version                              Show the program version\n");
859     fprintf(stream, "-viewport  [xmin ymin xmax ymax]      Set the viewport for the current graph\n");
860     fprintf(stream, "-wd        [directory]                Set the working directory\n");
861     fprintf(stream, "-world     [xmin ymin xmax ymax]      Set the world coordinates for the\n");
862     fprintf(stream, "                                        current graph\n");
863 
864     fprintf(stream, "-usage|-help                          This message\n");
865     fprintf(stream, "\n");
866     fprintf(stream, " ** If it scrolls too fast, run `%s -help | more\' **\n", progname);
867     exit(0);
868 }
869 
VersionInfo(void)870 static void VersionInfo(void)
871 {
872     int i;
873 
874     fprintf(stdout, "\n%s\n\n", bi_version_string());
875 
876 /* We don't want to reproduce the complete config.h,
877    but those settings which may be related to problems on runtime */
878 
879     fprintf(stdout, "GUI toolkit: %s\n", bi_gui());
880 #ifdef MOTIF_GUI
881     fprintf(stdout, "Xbae version: %s\n", bi_gui_xbae());
882 #endif
883     fprintf(stdout, "T1lib: %s\n", bi_t1lib());
884 #ifdef HAVE_FFTW
885     fprintf(stdout, "FFT: FFTW\n");
886 #else
887     fprintf(stdout, "FFT: built-in\n");
888 #endif
889 #ifdef HAVE_NETCDF
890     fprintf(stdout, "NetCDF support: on\n");
891 #else
892     fprintf(stdout, "NetCDF support: off\n");
893 #endif
894 #ifdef HAVE_LIBPNG
895 fprintf(stdout, "libpng: %s\n", bi_pnglib());
896 #endif
897 #ifdef HAVE_LIBJPEG
898 fprintf(stdout, "libjpeg: %s\n", bi_libjpeg());
899 #endif
900 #ifdef HAVE_LIBPDF
901 fprintf(stdout, "PDFlib: %s\n", bi_libpdf());
902 #endif
903 
904 
905 #ifdef DEBUG
906     fprintf(stdout, "Debugging: enabled\n");
907 #endif
908     fprintf(stdout, "Built: %s on %s\n", bi_date(), bi_system());
909     fprintf(stdout, "Compiler flags: %s\n", bi_ccompiler());
910 
911     fprintf(stdout, "\n");
912 
913     fprintf(stdout, "Registered devices:\n");
914     for (i = 0; i < number_of_devices(); i++) {
915         fprintf(stdout, "%s ", get_device_name(i));
916     }
917     fprintf(stdout, "\n\n");
918 
919     fprintf(stdout, "(C) Copyright 1991-1995 Paul J Turner\n");
920     fprintf(stdout, "(C) Copyright 1996-2015 Grace Development Team\n");
921     fprintf(stdout, "All Rights Reserved\n");
922 
923     return;
924 }
925