1 /* global.c
2 
3    MolScript v2.1.2
4 
5    Global stuff.
6 
7    Copyright (C) 1997-1998 Per Kraulis
8      1-Dec-1996  first attempts
9 */
10 
11 #include <assert.h>
12 #include <string.h>
13 
14 #include "clib/args.h"
15 #include "clib/str_utils.h"
16 
17 #include "global.h"
18 #include "lex.h"
19 #include "state.h"
20 #include "graphics.h"
21 #include "xform.h"
22 #include "postscript.h"
23 #include "raster3d.h"
24 #include "vrml.h"
25 
26 #ifdef OPENGL_SUPPORT
27 #include "opengl.h"
28 #ifdef IMAGE_SUPPORT
29 #include "image.h"
30 #include "eps_img.h"
31 #include "sgi_img.h"
32 #ifdef JPEG_SUPPORT
33 #include "jpeg_img.h"
34 #endif
35 #ifdef PNG_SUPPORT
36 #include "png_img.h"
37 #endif
38 #ifdef GIF_SUPPORT
39 #include "gif_img.h"
40 #endif
41 #endif
42 #endif
43 
44 
45 /*------------------------------------------------------------*/
46 const char program_str[] = "MolScript v2.1.2";
47 const char copyright_str[] = "Copyright (C) 1997-1998 Per J. Kraulis";
48 char user_str[81];
49 
50 int output_mode = UNDEFINED_MODE;
51 
52 char *input_filename = NULL;
53 char *output_filename = NULL;
54 char *tmp_filename = NULL;
55 FILE *outfile;
56 boolean message_mode = TRUE;
57 boolean exit_on_error = TRUE;
58 boolean pretty_format = FALSE;
59 int output_width = 500;
60 int output_height = 500;
61 
62 double dstack [MAX_DSTACK];
63 int dstack_size;
64 int ival;
65 
66 vector3 xaxis = {1.0, 0.0, 0.0};
67 vector3 yaxis = {0.0, 1.0, 0.0};
68 vector3 zaxis = {0.0, 0.0, 1.0};
69 
70 char *title = NULL;
71 boolean first_plot;
72 
73 
74 /*------------------------------------------------------------*/
75 void
banner(void)76 banner (void)
77 {
78   char *prefix = "-----";
79 
80   if (message_mode) {
81     fprintf (stderr, "%s %s, %s\n", prefix, program_str, copyright_str);
82     fprintf (stderr,
83 	     "%s ref: P.J. Kraulis, J. Appl. Cryst. (1991) vol 24, pp 946-950\n",
84 	     prefix);
85     fprintf (stderr, "%s http://www.avatar.se/molscript/\n", prefix);
86   }
87 }
88 
89 
90 /*------------------------------------------------------------*/
91 void
global_init(void)92 global_init (void)
93 {
94   outfile = stdout;
95   if (title) {
96     free (title);
97     title = NULL;
98   }
99   first_plot = TRUE;
100   xform_init_stored();
101   if (getenv ("USER") != NULL) {
102     strncpy (user_str, getenv ("USER"), 80);
103   } else {
104     user_str[0] = '\0';
105   }
106 }
107 
108 
109 /*------------------------------------------------------------*/
110 void
push_double(double d)111 push_double (double d)
112 {
113   assert (dstack_size < MAX_DSTACK);
114 
115   dstack[dstack_size++] = d;
116 }
117 
118 
119 /*------------------------------------------------------------*/
120 void
clear_dstack(void)121 clear_dstack (void)
122 {
123   dstack_size = 0;
124 }
125 
126 
127 /*------------------------------------------------------------*/
128 void
pop_dstack(int slots)129 pop_dstack (int slots)
130 {
131   assert (slots > 0);
132 
133   dstack_size -= slots;
134 
135   assert (dstack_size >= 0);
136 }
137 
138 
139 /*------------------------------------------------------------*/
140 void
do_nothing(void)141 do_nothing (void)
142 {
143   clear_dstack();
144 }
145 
146 
147 /*------------------------------------------------------------*/
148 void
do_nothing_str(char * str)149 do_nothing_str (char *str)
150 {
151   clear_dstack();
152 }
153 
154 
155 /*------------------------------------------------------------*/
156 void
not_implemented(const char * str)157 not_implemented (const char *str)
158 {
159   assert (str);
160 
161   fprintf (stderr, "feature %s not implemented\n", str);
162 }
163 
164 
165 /*------------------------------------------------------------*/
166 static void
argument_error(const char * msg,int slot)167 argument_error (const char *msg, int slot)
168 {
169   assert (msg);
170 
171   if (slot >= 0) {
172     fprintf (stderr, "Error: %s: %s\n", msg, args_item (slot));
173   } else {
174     fprintf (stderr, "Error: %s\n", msg);
175   }
176   exit (1);
177 }
178 
179 
180 /*------------------------------------------------------------*/
181 void
process_arguments(int * argcp,char * argv[])182 process_arguments (int *argcp, char *argv[])
183 {
184   int slot, slot2;
185   char *str;
186 
187   args_initialize (*argcp, argv);
188   args_flag (0);
189 
190   slot = args_exists ("-h");
191   if (slot) {
192     fprintf (stderr, "Usage: molscript [options] < script > outfile\n");
193     fprintf (stderr, "-ps -postscript      PostScript file output (default)\n");
194     fprintf (stderr, "-r -raster3d [alias] Raster3D file output (for 'render'), alias=1,2,3\n");
195     fprintf (stderr, "-vrml                VRML 2.0 file output\n");
196 #ifdef OPENGL_SUPPORT
197     fprintf (stderr, "-gl -opengl          OpenGL interactive graphics output (no file)\n");
198 #ifdef IMAGE_SUPPORT
199     fprintf (stderr, "-eps [scale]         Encapsulated PS image file output, scale>0.0 (default 1.0)\n");
200     fprintf (stderr, "-epsbw [scale]       Encapsulated PS black-and-white image file output\n");
201     fprintf (stderr, "-sgi -rgb            SGI (aka RGB) image file output\n");
202 #ifdef JPEG_SUPPORT
203     fprintf (stderr, "-jpeg [quality]      JPEG image file output, quality=1-100 (default 90)\n");
204 #endif
205 #ifdef PNG_SUPPORT
206     fprintf (stderr, "-png [compress]      PNG image file output, compress=default,none,speed,size\n");
207 #endif
208 #ifdef GIF_SUPPORT
209     fprintf (stderr, "-gif                 GIF image file output\n");
210 #endif
211 #endif
212     fprintf (stderr, "-accum number        image accumulation steps, number>=1 (only OpenGL & images)\n");
213 #endif
214     fprintf (stderr, "-pretty              nicely formatted output (VRML only)\n");
215     fprintf (stderr, "-size width height   size of output image (pixels; default 500 500)\n");
216     fprintf (stderr, "-s -silent           silent execution; no messages\n");
217     fprintf (stderr, "-out filename        output to the named file, instead of stdout\n");
218     fprintf (stderr, "-in filename         input from the named file, instead of stdin\n");
219     fprintf (stderr, "-log filename        messages to the named log file, instead of stderr\n");
220     fprintf (stderr, "-tmp filename        temporary file to use, if needed\n");
221     fprintf (stderr, "-h                   output this message\n");
222     banner();
223     exit (0);
224   }
225 
226   slot = args_exists ("-ps");
227   slot2 = args_exists ("-postscript");
228   if (slot || slot2) {
229     if (output_mode != UNDEFINED_MODE) goto format_error;
230     if (slot) args_flag (slot);
231     if (slot2) args_flag (slot2);
232     ps_set();
233   }
234 
235   slot = args_exists ("-r");
236   slot2 = args_exists ("-raster3d");
237   if (slot || slot2) {
238     if (output_mode != UNDEFINED_MODE) goto format_error;
239     r3d_set();
240     if (slot) args_flag (slot);
241     if (slot2) {
242       args_flag (slot2);
243       slot = slot2;
244     }
245     str = args_item (slot + 1);
246     if (str) {
247       int antialiasing;
248       if (sscanf (str, "%i", &antialiasing) == 1) {
249 	if (antialiasing < 1 || antialiasing > 3)
250 	  argument_error ("invalid antialiasing value for option -raster3d", slot + 1);
251 	args_flag (slot + 1);
252 	r3d_set_antialiasing (antialiasing);
253       }
254     }
255   }
256 
257   slot = args_exists ("-vrml");
258   if (slot) {
259     if (output_mode != UNDEFINED_MODE) goto format_error;
260     args_flag (slot);
261     vrml_set();
262   }
263 
264 #ifdef OPENGL_SUPPORT
265 
266   slot = args_exists ("-gl");
267   slot2 = args_exists ("-opengl");
268   if (slot || slot2) {
269     if (output_mode != UNDEFINED_MODE) goto format_error;
270     if (slot) args_flag (slot);
271     if (slot2) args_flag (slot2);
272     ogl_set();
273   }
274 
275 #ifdef IMAGE_SUPPORT
276 
277   slot = args_exists ("-eps");
278   slot2 = args_exists ("-epsbw");
279   if (slot || slot2) {
280     if (output_mode != UNDEFINED_MODE) goto format_error;
281     eps_set();
282     if (slot) args_flag (slot);
283     if (slot2) {
284       args_flag (slot2);
285       eps_set_bw();
286       slot = slot2;
287     }
288     str = args_item (slot + 1);
289     if (str) {
290       float scale;
291       if (sscanf (str, "%g", &scale) == 1) {
292 	if (scale <= 0.0)
293 	  argument_error ("invalid scale value for option -eps", slot + 1);
294 	args_flag (slot + 1);
295 	eps_set_scale (scale);
296       }
297     }
298   }
299 
300   slot = args_exists ("-sgi");
301   slot2 = args_exists ("-rgb");
302   if (slot || slot2) {
303     if (output_mode != UNDEFINED_MODE) goto format_error;
304     if (slot) args_flag (slot);
305     if (slot2) args_flag (slot2);
306     sgii_set();
307   }
308 
309 #ifdef JPEG_SUPPORT
310   slot = args_exists ("-jpeg");
311   if (slot) {
312     if (output_mode != UNDEFINED_MODE) goto format_error;
313     args_flag (slot);
314     jpgi_set();
315     str = args_item (slot + 1);
316     if (str) {
317       int quality;
318       if (sscanf (str, "%i", &quality) == 1) {
319 	if (quality <= 0 || quality > 100)
320 	  argument_error ("invalid quality value for option -jpeg", slot + 1);
321 	args_flag (slot + 1);
322 	jpgi_set_quality (quality);
323       }
324     }
325   }
326 #endif /* JPEG_SUPPORT */
327 
328 #ifdef PNG_SUPPORT
329   slot = args_exists ("-png");
330   if (slot) {
331     if (output_mode != UNDEFINED_MODE) goto format_error;
332     args_flag (slot);
333     pngi_set();
334     str = args_item (slot + 1);
335     if (str && pngi_set_compression (str)) args_flag (slot + 1);
336   }
337 #endif /* PNG_SUPPORT */
338 
339 #ifdef GIF_SUPPORT
340   slot = args_exists ("-gif");
341   if (slot) {
342     if (output_mode != UNDEFINED_MODE) goto format_error;
343     if (slot) args_flag (slot);
344     gifi_set();
345   }
346 #endif /*GIF_SUPPORT */
347 
348 #endif /* IMAGE_SUPPORT */
349 
350   slot = args_exists ("-accum");
351   if (slot) {
352     int number;
353     args_flag (slot);
354     str = args_item (slot + 1);
355     if (str) {
356       if ((sscanf (str, "%i", &number) != 1) || (number <= 0)) {
357 	argument_error ("invalid number for option -accum", slot + 1);
358       } else {
359 	ogl_set_accum (number);
360 	args_flag (slot + 1);
361       }
362     } else {
363       argument_error ("no number given for option -accum", -1);
364     }
365   }
366 
367 #endif /* OPENGL_SUPPORT */
368 
369   slot = args_exists ("-pretty");
370   if (slot) {
371     args_flag (slot);
372     pretty_format = TRUE;
373   }
374 
375   slot = args_exists ("-size");
376   if (slot) {
377     args_flag (slot);
378     str = args_item (slot + 1);
379     if (str) {
380       if ((sscanf (str, "%i", &output_width) != 1) ||
381 	  output_width < 1 || output_width > 4096)
382 	argument_error ("invalid width for option -size", slot + 1);
383       args_flag (slot + 1);
384       str = args_item (slot + 2);
385       if (str) {
386 	if ((sscanf (str, "%i", &output_height) != 1) ||
387 	    output_height < 1 || output_height > 4096)
388 	  argument_error ("invalid height for option -size", slot + 2);
389 	args_flag (slot + 2);
390       } else {
391 	argument_error ("no height given for option -size", -1);
392       }
393     } else {
394       argument_error ("no width given for option -size", -1);
395     }
396   }
397 
398   slot = args_exists ("-s");
399   slot2 = args_exists ("-silent");
400   if (slot || slot2) {
401     if (slot) args_flag (slot);
402     if (slot2) args_flag (slot2);
403     message_mode = FALSE;
404   }
405 
406   slot = args_exists ("-out");
407   if (slot) {
408     str = args_item (slot + 1);
409     args_flag (slot);
410     if (str) {
411       args_flag (slot + 1);
412       output_filename = str;
413     } else {
414       argument_error ("no filename given for option -out", -1);
415     }
416   }
417 
418   slot = args_exists ("-in");
419   if (slot) {
420     args_flag (slot);
421     input_filename = str_clone (args_item (slot + 1));
422     if (input_filename) {
423       lex_set_input_file (input_filename);
424       if (lex_input_file() == NULL)
425 	argument_error ("could not open the input file", slot + 1);
426       args_flag (slot + 1);
427     } else {
428       argument_error ("no filename given for option -in", -1);
429     }
430   }
431 
432   slot = args_exists ("-log");
433   if (slot) {
434     FILE *file;
435     args_flag (slot);
436     str = args_item (slot + 1);
437     if (str) {
438       file = freopen (str, "w", stderr);
439       if (file == NULL)
440 	argument_error ("could not open the log file", slot + 1);
441       args_flag (slot + 1);
442     } else {
443       argument_error ("no filename given for option -log", -1);
444     }
445   }
446 
447   slot = args_exists ("-tmp");
448   if (slot) {
449     args_flag (slot);
450     str = args_item (slot + 1);
451     if (str) {
452       tmp_filename = str;
453       args_flag (slot + 1);
454     } else {
455       argument_error ("no filename given for option -tmp", -1);
456     }
457   }
458 
459   if (args_unflagged() >= 0)
460     argument_error ("invalid command line option", args_unflagged());
461 
462   if (output_mode == UNDEFINED_MODE) ps_set();
463 
464   return;
465 
466 format_error:
467   argument_error ("more than one format options given", slot);
468 }
469 
470 
471 /*------------------------------------------------------------*/
472 void
set_outfile(const char * mode)473 set_outfile (const char *mode)
474 {
475   assert (mode);
476   assert (*mode);
477 
478   if (output_filename) {
479     outfile = fopen (output_filename, mode);
480     if (outfile == NULL) yyerror ("could not create the output file");
481     output_filename = NULL;
482   }
483 }
484 
485 
486 /*------------------------------------------------------------*/
487 void
set_title(const char * str)488 set_title (const char *str)
489 {
490   assert (str);
491   assert (*str);
492 
493   title = str_clone (str);
494 }
495 
496 
497 /*------------------------------------------------------------*/
498 void
start_plot(void)499 start_plot (void)
500 {
501   output_first_plot();
502   first_plot = FALSE;
503 
504   state_init();
505   graphics_plot_init();
506   delete_all_molecules();
507   xform_init();
508   clear_dstack();
509 
510   output_start_plot();
511 }
512 
513 
514 /*------------------------------------------------------------*/
515 void
debug(const char * str)516 debug (const char *str)
517 {
518   assert (str);
519 
520   if (message_mode) fprintf (stderr, "%s\n", str);
521 }
522