Reset parser in grace_set_project().
[grace.git] / src / main.c
blob95d313415a11e896192d42917c74de3f512e761a
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-2004 Grace Development Team
8 *
9 * Maintained by Evgeny Stambulchik
12 * All Rights Reserved
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.
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.
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.
29 #include <config.h>
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
39 /* for globals.h */
40 #define MAIN
42 #include "globals.h"
44 #include "utils.h"
45 #include "files.h"
46 #include "ssdata.h"
48 #include "dicts.h"
49 #include "plotone.h"
51 #include "devlist.h"
52 #include "parser.h"
53 #include "protos.h"
56 extern Input_buffer *ib_tbl;
57 extern int ib_tblsize;
59 static void usage(FILE *stream, char *progname);
60 static void VersionInfo(const Grace *grace);
61 static void cli_loop(Grace *grace);
63 #if defined(DEBUG)
64 extern int yydebug;
65 #endif
67 int main(int argc, char *argv[])
69 char *s;
70 int i;
71 int fd;
72 Quark *cur_graph; /* default (current) graph */
73 int gracebat; /* if executed as 'gracebat' then TRUE */
74 int cli = FALSE; /* command line interface only */
75 int noprint = FALSE; /* if gracebat, then don't print if true */
76 int sigcatch = TRUE; /* we handle signals ourselves */
78 char fd_name[GR_MAXPATHLEN];
80 int wpp, hpp;
82 RunTime *rt;
83 GUI *gui;
84 Canvas *canvas;
86 grace = grace_new();
87 if (!grace) {
88 errmsg("Failed to allocate run-time structures");
89 exit(1);
92 rt = grace->rt;
93 canvas = rt->canvas;
94 gui = grace->gui;
96 if (init_font_db(canvas)) {
97 errmsg("Broken or incomplete installation - read the FAQ!");
98 exit(1);
101 /* initialize the parser symbol table */
102 init_symtab();
104 /* initialize the rng */
105 srand48(100L);
108 * if program name is gracebat* then don't initialize the X toolkit
110 s = mybasename(argv[0]);
112 if (strstr(s, "gracebat") == s) {
113 gracebat = TRUE;
114 } else {
115 gracebat = FALSE;
116 if (strstr(s, "grace") == s) {
117 cli = TRUE;
118 } else {
119 #ifndef NONE_GUI
120 cli = FALSE;
121 if (initialize_gui(&argc, argv) != RETURN_SUCCESS) {
122 errmsg("Failed initializing GUI, exiting");
123 exit(1);
125 #endif
129 /* initialize devices */
130 #ifndef NONE_GUI
131 if (cli == TRUE || gracebat == TRUE) {
132 rt->tdevice = register_dummy_drv(canvas);
133 } else {
134 rt->tdevice = register_x11_drv(canvas);
136 #else
137 rt->tdevice = register_dummy_drv(canvas);
138 #endif
140 rt->hdevice = register_ps_drv(canvas);
141 register_eps_drv(canvas);
143 #ifdef HAVE_LIBPDF
144 register_pdf_drv(canvas);
145 #endif
146 register_mif_drv(canvas);
147 register_svg_drv(canvas);
149 #ifdef HAVE_LIBXMI
150 register_pnm_drv(canvas);
151 # ifdef HAVE_LIBJPEG
152 register_jpg_drv(canvas);
153 # endif
154 # ifdef HAVE_LIBPNG
155 register_png_drv(canvas);
156 # endif
157 #endif
159 register_mf_drv(canvas);
161 /* check whether locale is correctly set */
162 if (init_locale() != RETURN_SUCCESS) {
163 errmsg("Invalid or unsupported locale");
165 /* default is POSIX */
166 set_locale_num(FALSE);
168 /* load startup file */
169 getparms(grace, "gracerc");
171 /* load default template */
172 new_project(grace, NULL);
174 cur_graph = graph_get_current(grace->project);
176 for (i = 1; i < argc; i++) {
177 if (argv[i][0] == '-' && argv[i][1] != '\0') {
178 if (argmatch(argv[i], "-version", 2)) {
179 VersionInfo(grace);
180 exit(0);
182 #if defined(DEBUG)
183 if (argmatch(argv[i], "-debug", 6)) {
184 i++;
185 if (i == argc) {
186 fprintf(stderr, "Missing argument for debug flag\n");
187 usage(stderr, argv[0]);
188 } else {
189 set_debuglevel(grace, atoi(argv[i]));
190 if (get_debuglevel(grace) == 4) {
191 /* turn on debugging in pars.y */
192 yydebug = TRUE;
195 } else
196 #endif
197 if (argmatch(argv[i], "-nosigcatch", 6)) {
198 sigcatch = FALSE;
199 } else if (argmatch(argv[i], "-autoscale", 2)) {
200 i++;
201 if (i == argc) {
202 errmsg("Missing argument for autoscale flag");
203 usage(stderr, argv[0]);
204 } else {
205 if (!strcmp("x", argv[i])) {
206 rt->autoscale_onread = AUTOSCALE_X;
207 } else if (!strcmp("y", argv[i])) {
208 rt->autoscale_onread = AUTOSCALE_Y;
209 } else if (!strcmp("xy", argv[i])) {
210 rt->autoscale_onread = AUTOSCALE_XY;
211 } else if (!strcmp("none", argv[i])) {
212 rt->autoscale_onread = AUTOSCALE_NONE;
213 } else {
214 errmsg("Improper argument for autoscale flag");
215 usage(stderr, argv[0]);
218 } else if (argmatch(argv[i], "-datehint", 5)) {
219 i++;
220 if (i == argc) {
221 errmsg("Missing argument for datehint flag");
222 usage(stderr, argv[0]);
223 } else {
224 if (!strcmp("iso", argv[i])) {
225 set_date_hint(FMT_iso);
226 } else if (!strcmp("european", argv[i])) {
227 set_date_hint(FMT_european);
228 } else if (!strcmp("us", argv[i])) {
229 set_date_hint(FMT_us);
230 } else if (!strcmp("nohint", argv[i])) {
231 set_date_hint(FMT_nohint);
232 } else {
233 errmsg("Improper argument for datehint flag");
234 usage(stderr, argv[0]);
237 } else if (argmatch(argv[i], "-noprint", 8)) {
238 noprint = TRUE;
239 } else if (argmatch(argv[i], "-dpipe", 6)) {
240 i++;
241 if (i == argc) {
242 fprintf(stderr, "Missing argument for descriptor pipe\n");
243 usage(stderr, argv[0]);
244 } else {
245 fd = atoi(argv[i]);
246 sprintf(fd_name, "pipe<%d>", fd);
247 if (register_real_time_input(grace, fd, fd_name, FALSE) !=
248 RETURN_SUCCESS) {
249 exit(1);
252 } else if (argmatch(argv[i], "-npipe", 6)) {
253 i++;
254 if (i == argc) {
255 fprintf(stderr, "Missing argument for named pipe\n");
256 usage(stderr, argv[0]);
257 } else {
258 fd = open(argv[i], O_RDONLY | O_NONBLOCK);
259 if (fd < 0) {
260 fprintf(stderr, "Can't open fifo\n");
261 } else {
262 if (register_real_time_input(grace, fd, argv[i], TRUE) !=
263 RETURN_SUCCESS) {
264 exit(1);
268 } else if (argmatch(argv[i], "-timer", 6)) {
269 i++;
270 if (i == argc) {
271 fprintf(stderr, "Missing argument for time delay\n");
272 usage(stderr, argv[0]);
273 } else {
274 rt->timer_delay = atoi(argv[i]);
276 #ifndef NONE_GUI
277 } else if (argmatch(argv[i], "-install", 7)) {
278 gui->install_cmap = CMAP_INSTALL_ALWAYS;
279 } else if (argmatch(argv[i], "-noinstall", 9)) {
280 gui->install_cmap = CMAP_INSTALL_NEVER;
281 } else if (argmatch(argv[i], "-barebones", 9)) {
282 gui_set_barebones(gui);
283 #endif
284 } else if (argmatch(argv[i], "-fixed", 5)) {
285 i++;
286 if (i == argc) {
287 fprintf(stderr, "Missing argument for fixed canvas width\n");
288 usage(stderr, argv[0]);
289 } else {
290 if (i == argc - 1) {
291 fprintf(stderr, "Missing argument for fixed canvas height\n");
292 usage(stderr, argv[0]);
293 } else {
294 wpp = atoi(argv[i]);
295 i++;
296 hpp = atoi(argv[i]);
297 set_page_dimensions(grace, wpp, hpp, FALSE);
298 #ifndef NONE_GUI
299 gui_set_page_free(gui, FALSE);
300 #endif
303 #ifndef NONE_GUI
304 } else if (argmatch(argv[i], "-free", 5)) {
305 gui_set_page_free(gui, TRUE);
306 #endif
307 } else if (argmatch(argv[i], "-noask", 5)) {
308 gui->noask = TRUE;
309 } else if (argmatch(argv[i], "-hdevice", 5)) {
310 i++;
311 if (i == argc) {
312 fprintf(stderr, "Missing argument for hardcopy device select flag\n");
313 usage(stderr, argv[0]);
314 } else {
315 if (set_printer_by_name(grace, argv[i]) != RETURN_SUCCESS) {
316 errmsg("Unknown or unsupported device");
317 exit(1);
320 } else if (argmatch(argv[i], "-hdevice-options", 12)) {
321 i++;
322 if (i == argc) {
323 fprintf(stderr, "Missing argument for hardcopy device options\n");
324 usage(stderr, argv[0]);
325 } else {
326 if (parse_device_options(rt->canvas,
327 rt->hdevice, argv[i]) != RETURN_SUCCESS) {
328 errmsg("Failed parsing device options");
329 exit(1);
332 } else if (argmatch(argv[i], "-printfile", 6)) {
333 i++;
334 if (i == argc) {
335 fprintf(stderr, "Missing file name for printing\n");
336 usage(stderr, argv[0]);
337 } else {
338 set_ptofile(grace, TRUE);
339 strcpy(rt->print_file, argv[i]);
341 } else if (argmatch(argv[i], "-hardcopy", 6)) {
342 gracebat = TRUE;
343 } else if (argmatch(argv[i], "-pexec", 6)) {
344 i++;
345 if (i == argc) {
346 fprintf(stderr, "Missing argument for exec\n");
347 usage(stderr, argv[0]);
348 } else {
349 scanner(argv[i]);
351 } else if (argmatch(argv[i], "-block", 6)) {
352 i++;
353 if (i == argc) {
354 fprintf(stderr, "Missing filename for block data\n");
355 usage(stderr, argv[0]);
356 } else {
357 getdata(grace->project, argv[i], rt->cursource, LOAD_BLOCK);
359 } else if (argmatch(argv[i], "-bxy", 4)) {
360 i++;
361 if (i == argc) {
362 fprintf(stderr, "Missing parameter for block data set creation\n");
363 usage(stderr, argv[0]);
364 } else {
365 int nc, *cols, scol;
366 if (field_string_to_cols(argv[i], &nc, &cols, &scol) !=
367 RETURN_SUCCESS) {
368 errmsg("Erroneous field specifications");
369 return 1;
371 create_set_fromblock(grace_set_new(cur_graph),
372 rt->curtype, nc, cols, scol, rt->autoscale_onread);
373 xfree(cols);
375 } else if (argmatch(argv[i], "-nxy", 4)) {
376 i++;
377 if (i == argc) {
378 fprintf(stderr, "Missing filename for nxy data\n");
379 usage(stderr, argv[0]);
380 } else {
381 getdata(grace->project, argv[i], rt->cursource, LOAD_NXY);
383 } else if (argmatch(argv[i], "-type", 2) ||
384 argmatch(argv[i], "-settype", 8)) {
385 /* set types */
386 i++;
387 rt->curtype = get_settype_by_name(rt, argv[i]);
388 if (rt->curtype == -1) {
389 fprintf(stderr, "%s: Unknown set type '%s'\n", argv[0], argv[i]);
390 usage(stderr, argv[0]);
392 } else if (argmatch(argv[i], "-param", 2)) {
393 i++;
394 if (i == argc) {
395 fprintf(stderr, "Missing parameter file name\n");
396 usage(stderr, argv[0]);
397 } else {
398 if (!getparms(grace, argv[i])) {
399 fprintf(stderr, "Unable to read parameter file %s\n", argv[i]);
402 } else if (argmatch(argv[i], "-results", 2)) {
403 i++;
404 if (i == argc) {
405 fprintf(stderr, "Missing results file name\n");
406 usage(stderr, argv[0]);
407 } else {
408 /* open resfile if -results option given */
409 if ((rt->resfp = grace_openw(grace, argv[i])) == NULL) {
410 exit(1);
412 setvbuf(rt->resfp, NULL, _IOLBF, 0);
414 } else if (argmatch(argv[i], "-saveall", 8)) {
415 i++;
416 if (i == argc) {
417 fprintf(stderr, "Missing save file name\n");
418 usage(stderr, argv[0]);
419 } else {
420 save_project(grace->project, argv[i]);
422 } else if (argmatch(argv[i], "-wd", 3)) {
423 i++;
424 if (i == argc) {
425 fprintf(stderr, "Missing parameters for working directory\n");
426 usage(stderr, argv[0]);
427 } else {
428 if (set_workingdir(grace, argv[i]) != RETURN_SUCCESS) {
429 fprintf(stderr, "Can't change to directory %s, fatal error", argv[i]);
430 exit(1);
433 } else if (argmatch(argv[i], "-source", 2)) {
434 i++;
435 if (i == argc) {
436 fprintf(stderr, "Missing argument for data source parameter\n");
437 usage(stderr, argv[0]);
439 if (argmatch(argv[i], "pipe", 4)) {
440 rt->cursource = SOURCE_PIPE;
441 } else if (argmatch(argv[i], "disk", 4)) {
442 rt->cursource = SOURCE_DISK;
444 } else if (argmatch(argv[i], "-seed", 5)) {
445 i++;
446 if (i == argc) {
447 fprintf(stderr, "Missing seed for srand48()\n");
448 usage(stderr, argv[0]);
449 } else {
450 srand48(atol(argv[i])); /* note atol() */
452 } else if (argmatch(argv[i], "-safe", 5)) {
453 grace->rt->safe_mode = TRUE;
454 } else if (argmatch(argv[i], "-nosafe", 7)) {
455 grace->rt->safe_mode = FALSE;
456 } else if (argmatch(argv[i], "-help", 2)) {
457 usage(stdout, argv[0]);
458 } else if (argmatch(argv[i], "-usage", 5)) {
459 usage(stdout, argv[0]);
460 } else {
461 fprintf(stderr, "No option %s\n", argv[i]);
462 usage(stderr, argv[0]);
464 } else {
465 if (strstr(argv[i], ".xgr") || strstr(argv[i], ".agr")) {
466 load_project(grace, argv[i]);
467 } else {
468 getdata(grace->project, argv[i], rt->cursource, LOAD_SINGLE);
470 } /* end else */
471 } /* end for */
474 * Process events.
476 if (sigcatch == TRUE) {
477 installSignal();
481 * if -hardcopy on command line or executed as gracebat,
482 * just plot the graph and quit
484 if (gracebat == TRUE) {
485 if (rt->hdevice == 0) {
486 errmsg("Terminal device can't be used for batch plotting");
487 exit(1);
489 while (real_time_under_monitoring()) {
490 monitor_input(grace, ib_tbl, ib_tblsize, 0);
492 if (!noprint) {
493 do_hardcopy(grace->project);
496 bailout(grace);
497 } else {
499 * go main loop
501 #ifndef NONE_GUI
502 if (cli == TRUE) {
503 cli_loop(grace);
504 } else {
505 startup_gui(grace);
507 #else
508 cli_loop(grace);
509 #endif
511 /* never reaches */
512 exit(0);
516 * command interface loop
518 static void cli_loop(Grace *grace)
520 Input_buffer *ib_stdin;
521 int previous = -1;
523 if (register_real_time_input(grace, STDIN_FILENO, "stdin", 0)
524 != RETURN_SUCCESS) {
525 exit(1);
527 for (ib_stdin = ib_tbl; ib_stdin->fd != STDIN_FILENO; ib_stdin++) {
531 while (ib_stdin->fd == STDIN_FILENO) {
532 /* the standard input is still under monitoring */
533 if (ib_stdin->lineno != previous) {
534 printf("grace:%d> ", ib_stdin->lineno + 1);
535 fflush(stdout);
536 previous = ib_stdin->lineno;
538 monitor_input(grace, ib_tbl, ib_tblsize, 0);
543 static void usage(FILE *stream, char *progname)
545 /* We use alphabetical order */
547 fprintf(stream, "Usage of %s command line arguments: \n", progname);
549 fprintf(stream, "-autoscale [x|y|xy|none] Set autoscale type\n");
550 #ifndef NONE_GUI
551 fprintf(stream, "-barebones Turn off all toolbars\n");
552 #endif
553 fprintf(stream, "-block [block_data] Assume data file is block data\n");
554 fprintf(stream, "-bxy [x:y:etc.] Form a set from the current block data set\n");
555 fprintf(stream, " using the current set type from columns\n");
556 fprintf(stream, " given in the argument\n");
557 fprintf(stream, "-datehint [iso|european|us\n");
558 fprintf(stream, " |days|seconds|nohint] Set the hint for dates analysis\n");
559 fprintf(stream, " (it is only a hint for the parser)\n");
560 #if defined(DEBUG)
561 fprintf(stream, "-debug [debug_level] Set debugging options\n");
562 #endif
563 fprintf(stream, "-dpipe [descriptor] Read data from descriptor on startup\n");
564 fprintf(stream, "-fixed [width] [height] Set canvas size fixed to width*height\n");
565 #ifndef NONE_GUI
566 fprintf(stream, "-free Use free page layout\n");
567 #endif
568 fprintf(stream, "-hardcopy No interactive session, just print and\n");
569 fprintf(stream, " quit\n");
570 fprintf(stream, "-hdevice [hardcopy_device_name] Set default hardcopy device\n");
571 fprintf(stream, "-hdevice-options [option_string] Set options for default hardcopy device\n");
572 #ifndef NONE_GUI
573 fprintf(stream, "-install Install private colormap\n");
574 #endif
575 fprintf(stream, "-noask Assume the answer is yes to all requests -\n");
576 fprintf(stream, " if the operation would overwrite a file,\n");
577 fprintf(stream, " grace will do so without prompting\n");
578 #ifndef NONE_GUI
579 fprintf(stream, "-noinstall Don't use private colormap\n");
580 #endif
581 fprintf(stream, "-noprint In batch mode, do not print\n");
582 fprintf(stream, "-nosafe Disable safe mode\n");
583 fprintf(stream, "-nosigcatch Don't catch signals\n");
584 fprintf(stream, "-npipe [file] Read data from named pipe on startup\n");
585 fprintf(stream, "-nxy [nxy_file] Assume data file is in X Y1 Y2 Y3 ...\n");
586 fprintf(stream, " format\n");
587 fprintf(stream, "-param [parameter_file] Load parameters from parameter_file to the\n");
588 fprintf(stream, " current graph\n");
589 fprintf(stream, "-pexec [parameter_string] Interpret string as a parameter setting\n");
590 fprintf(stream, "-printfile [file for hardcopy output] Save print output to file \n");
591 fprintf(stream, "-results [results_file] Write results of some data manipulations\n");
592 fprintf(stream, " to results_file\n");
593 fprintf(stream, "-safe Safe mode (default)\n");
594 fprintf(stream, "-saveall [save_file] Save all to save_file\n");
595 fprintf(stream, "-seed [seed_value] Integer seed for random number generator\n");
596 fprintf(stream, "-source [disk|pipe] Source type of next data file\n");
597 fprintf(stream, "-timer [delay] Set allowed time slice for real time\n");
598 fprintf(stream, " inputs to delay ms\n");
599 fprintf(stream, "-settype [xy|xydx|...] Set the type of the next data file\n");
600 fprintf(stream, "-version Show the program version\n");
601 fprintf(stream, "-wd [directory] Set the working directory\n");
603 fprintf(stream, "-usage|-help This message\n");
604 fprintf(stream, "\n");
605 fprintf(stream, " ** If it scrolls too fast, run `%s -help | more\' **\n", progname);
606 exit(0);
609 static void VersionInfo(const Grace *grace)
611 int i;
613 fprintf(stdout, "\n%s\n\n", bi_version_string());
615 /* We don't want to reproduce the complete config.h,
616 but those settings which may be related to problems on runtime */
618 fprintf(stdout, "GUI toolkit: %s\n", bi_gui());
619 #ifdef MOTIF_GUI
620 fprintf(stdout, "Xbae version: %s\n", bi_gui_xbae());
621 #endif
622 fprintf(stdout, "T1lib: %s\n", bi_t1lib());
623 #ifdef HAVE_FFTW
624 fprintf(stdout, "FFT: FFTW\n");
625 #else
626 fprintf(stdout, "FFT: built-in\n");
627 #endif
628 #ifdef HAVE_NETCDF
629 fprintf(stdout, "NetCDF support: on\n");
630 #else
631 fprintf(stdout, "NetCDF support: off\n");
632 #endif
634 #ifdef DEBUG
635 fprintf(stdout, "Debugging: enabled\n");
636 #endif
637 fprintf(stdout, "Built: %s on %s\n", bi_date(), bi_system());
638 fprintf(stdout, "Compiler flags: %s\n", bi_ccompiler());
640 fprintf(stdout, "\n");
642 fprintf(stdout, "Registered devices:\n");
643 for (i = 0; i < number_of_devices(grace->rt->canvas); i++) {
644 fprintf(stdout, "%s ", get_device_name(grace->rt->canvas, i));
646 fprintf(stdout, "\n\n");
648 fprintf(stdout, "(C) Copyright 1991-1995 Paul J Turner\n");
649 fprintf(stdout, "(C) Copyright 1996-2004 Grace Development Team\n");
650 fprintf(stdout, "All Rights Reserved\n");
652 return;