r115: *** empty log message ***
[ctsim.git] / libctgraphics / ezset.cpp
1 /*****************************************************************************
2 **  FILE IDENTIFICATION
3 **
4 **      EZSET - Parameter control for EZPLOT            
5 **
6 **  This is part of the CTSim program
7 **  Copyright (C) 1983-2000 Kevin Rosenberg
8 **
9 **  $Id: ezset.cpp,v 1.3 2000/06/20 17:54:51 kevin Exp $
10 **
11 **  This program is free software; you can redistribute it and/or modify
12 **  it under the terms of the GNU General Public License (version 2) as
13 **  published by the Free Software Foundation.
14 **
15 **  This program is distributed in the hope that it will be useful,
16 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
17 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 **  GNU General Public License for more details.
19 **
20 **  You should have received a copy of the GNU General Public License
21 **  along with this program; if not, write to the Free Software
22 **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 ******************************************************************************/
24 /*----------------------------------------------------------------------*/
25 /*                                                                      */
26 /*----------------------------------------------------------------------*/
27
28 #include "ctsupport.h"
29 #include "ezplot.h"
30 #include "pol.h"
31
32 static int ezcmd (char *comm);
33 static int do_cmd(int lx);
34 static void do_data(void);
35 static void do_help(void);
36 static void bad_option(char *opt);
37 static void initkw(void);
38
39 static int modeinteract = FALSE;
40 static int curveinteract = -1;
41 static int ezset_firstcall = TRUE;
42 static int eztrace = TRUE;
43
44 int 
45 ezset (char *command)
46 {
47     if (ezplot_firstcall == TRUE) {
48         ezinit ();
49     }
50     if (ezset_firstcall == TRUE) {
51         pol_init();
52         initkw();
53         pol_skpword ("please");
54         pol_skpword ("use");
55         pol_skpword ("are");
56         pol_skpword ("and");
57         pol_skpword ("is");
58         pol_skpword ("the");
59         pol_skpword ("equals");
60         pol_skpchar ("=");
61         ezset_firstcall = FALSE;
62
63         pol_usefile (P_USE_STR,"");
64         set_inputline ("!eoc ,");
65         pol_reader ();
66         pol_closefile ();
67     }
68     return (ezcmd (command));
69 }
70
71 static int 
72 ezcmd (char *comm)
73 {
74         char str[MAXTOK+1];
75         int code, retval;
76
77         retval = TRUE;
78         pol_usefile (P_USE_STR, "");
79         set_inputline (comm);
80
81         if (pol_usertok (str, &code) == FALSE) {
82             fputs("Illegal EZSET command\n", stderr);
83             pol_reader();
84             retval = FALSE;
85             goto ezexit;
86         }
87
88         if (code != S_INTERACTIVE) {
89             retval = do_cmd (code);
90         } else {
91             modeinteract = TRUE;
92             pol_reader();
93             do {
94                 fputs ("Enter EZSET command, DATA, EXIT, or HELP\n>", stderr);
95                 if (get_inputline (stdin) != TRUE)
96                     goto ezexit;
97                 while (pol_lookchar() != EOF) {
98                     if (pol_usertok (str, &code) == FALSE) {
99                         if (pol_lookchar() != EOF) {
100                             fputs ("illegal EZSET command\n", stderr);
101                             pol_reader();
102                         }
103                     } else if (code == S_DATA) {
104                         pol_reader ();
105                         do_data ();
106                     } else if (code == S_HELP) {
107                         pol_reader();
108                         do_help ();
109                     } else if (code == S_EXIT) {
110                         pol_reader();
111                         goto ezexit;
112                     } else
113                         do_cmd (code);
114                 }
115                 putc (NEWLINE, stderr);
116             } while (TRUE);
117             modeinteract = FALSE;
118             curveinteract = -1;
119         }
120 ezexit:
121         pol_closefile();                        /* close input string file */
122         return (retval);
123 }
124
125
126 static int 
127 do_cmd (int lx)
128 {
129         char str [MAXTOK+1];
130         int n;
131         double f;
132
133         switch (lx) {
134             case S_CRT:
135                 if (pol_word("no", 2) == TRUE)
136                     ez.d_usecrt = FALSE;
137                 else {
138                     ez.d_usecrt = TRUE;
139                 }
140                 break;
141             case S_EPSON:
142                 if (pol_word("no", 2) == TRUE)
143                     ez.d_useprt = FALSE;
144                 else
145                     ez.d_useprt = TRUE;
146                 break;
147             case S_TEXTSIZE:
148                 if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
149                   {
150                     if (f >= 0.0 && f <= 1.0) {
151                         ez.v_textsize = f;
152                         ez.s_textsize = TRUE;
153                     } else
154                         ez.s_textsize = FALSE;
155                   }
156                 break;
157             case S_PRTMODE:
158                 if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
159                   {
160                     if (n >= 0 && n <= 6)
161                         ez.d_prtmode = n;
162                     else
163                         ez.d_prtmode = PRTMODE_DEF;
164                   }
165                 break;
166             case S_XBUF:
167                 if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
168                   {
169                     if (n > 2 && n <= 960)
170                         ez.d_xprtbuf = n;
171                     else
172                         ez.d_xprtbuf = XBUF_DEF;
173                   }
174                 break;
175             case S_YBUF:
176                 if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
177                   {
178                     if (n > 2 && n <= 960)
179                         ez.d_yprtbuf = n;
180                     else
181                         ez.d_yprtbuf = YBUF_DEF;
182                   }
183                 break;
184             case S_REPLOT:
185                 ez.i_plotimmediate = TRUE;
186                 ezplot (static_cast<double*>(NULL), static_cast<double*>(NULL), 0);
187 #if 0
188                 if (modeinteract == TRUE)
189                     WAITKEY();
190 #endif
191                 ez.i_plotimmediate = FALSE;
192                 break;
193             case S_CLEAR:
194                 ezclear ();
195                 break;
196             case S_TITLE:
197                 gettext (ez.c_title, MAXTITLE);
198                 break;
199             case S_LEGEND:
200                 gettext (ez.c_legend, MAXLEGEND);
201                 if (modeinteract == TRUE && curveinteract >= 0)
202                     strncpy (ez.curve[curveinteract].legend, ez.c_legend, MAXLEGEND);
203                 break;
204             case S_XLABEL:
205                 gettext (ez.c_xlabel, MAXLABEL);
206                 break;
207             case S_YLABEL:
208                 gettext (ez.c_ylabel, MAXLABEL);
209                 break;
210             case S_XCROSS:
211                 if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
212                     ez.v_xcross = f;
213                     ez.s_xcross = TRUE;
214                 } else
215                     ez.s_xcross = FALSE;
216                 break;
217             case S_YCROSS:
218                 if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
219                     ez.v_ycross = f;
220                     ez.s_ycross = TRUE;
221                 } else
222                     ez.s_ycross = FALSE;
223                 break;
224             case S_NOXAXIS:
225                 ez.o_xaxis = NOAXIS;
226                 break;
227             case S_NOYAXIS:
228                 ez.o_yaxis = NOAXIS;
229                 break;
230             case S_XLIN:
231                 ez.o_xaxis = LINEAR;
232                 break;
233             case S_YLIN:
234                 ez.o_yaxis = LINEAR;
235                 break;
236             case S_XLOG:
237                 ez.o_xaxis = LOG;
238                 break;
239             case S_YLOG:
240                 ez.o_yaxis = LOG;
241                 break;
242             case S_XAUTOSCALE:
243                 ez.s_xmin = FALSE;
244                 ez.s_xmax = FALSE;
245                 break;
246             case S_YAUTOSCALE:
247                 ez.s_ymin = FALSE;
248                 ez.s_ymax = FALSE;
249                 break;
250             case S_XMIN:
251                 if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
252                     ez.v_xmin = f;
253                     ez.s_xmin = TRUE;
254                 }
255                 break;
256             case S_XMAX:
257                 if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
258                     ez.v_xmax = f;
259                     ez.s_xmax = TRUE;
260                 }
261                 break;
262             case S_YMIN:
263                 if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
264                     ez.v_ymin = f;
265                     ez.s_ymin = TRUE;
266                 }
267                 break;
268             case S_YMAX:
269                 if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
270                     ez.v_ymax = f;
271                     ez.s_ymax = TRUE;
272                 }
273                 break;
274             case S_SOLID:
275                 ez.o_linestyle = LS_SOLID;
276                 if (modeinteract == TRUE && curveinteract >= 0)
277                     ez.curve[curveinteract].linestyle = LS_SOLID;
278                 break;
279             case S_DASH:
280                 if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE) {
281                     if (n == 1)
282                         ez.o_linestyle = LS_DASH1;
283                     else if (n == 2)
284                         ez.o_linestyle = LS_DASH2;
285                     else if (n == 3)
286                         ez.o_linestyle = LS_DASH3;
287                     else if (n == 4)
288                         ez.o_linestyle = LS_DASH4;
289                     else
290                         ez.o_linestyle = LS_DASH1;
291                 } else
292                     ez.o_linestyle = LS_DASH1;
293                 if (modeinteract == TRUE && curveinteract >= 0)
294                     ez.curve[curveinteract].linestyle = ez.o_linestyle;
295                 break;
296             case S_NOLINE:
297                 ez.o_linestyle = LS_NOLINE;
298                 if (modeinteract == TRUE && curveinteract >= 0)
299                     ez.curve[curveinteract].linestyle = LS_NOLINE;
300                 break;
301             case S_PEN:
302             case S_COLOR:
303                 if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
304                   {
305                     if (n >= 0 && n <= MAXCOLOR)
306                         ez.o_color = n;
307                     else
308                         bad_option("The color you picked");
309                   }
310                 if (modeinteract == TRUE && curveinteract >= 0)
311                     ez.curve[curveinteract].color = ez.o_color;
312                 break;
313             case S_BOX:
314                 ez.o_box = TRUE;
315                 break;
316             case S_NOBOX:
317                 ez.o_box = FALSE;
318                 break;
319             case S_GRID:
320                 ez.o_grid = TRUE;
321                 break;
322             case S_NOGRID:
323                 ez.o_grid = FALSE;
324                 break;
325             case S_XLENGTH:
326                 if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
327                     if (f > 0.0 && f <= 1.0)
328                         ez.o_xlength = f;
329                 break;
330             case S_YLENGTH:
331                 if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
332                     if (f > 0.0 && f <= 1.0)
333                         ez.o_ylength = f;
334                 break;
335             case S_XPORIGIN:
336                 if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
337                     if (f >= 0.0 && f < 1.0)
338                         ez.o_xporigin = f;
339                 break;
340             case S_YPORIGIN:
341                 if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
342                     if (f >= 0.0 && f < 1.0)
343                         ez.o_yporigin = f;
344                 break;
345             case S_TAG:
346                 if (pol_word("no", 2) == TRUE)
347                     ez.o_tag = FALSE;
348                 else if (pol_word("off", 2) == TRUE)
349                     ez.o_tag = FALSE;
350                 else
351                     ez.o_tag = TRUE;
352                 break;
353             case S_LEGENDBOX:
354                 if (pol_word("inside", 2) == TRUE)
355                     ez.o_legendbox = INSIDE;
356                 else if (pol_word("outside", 3) == TRUE)
357                     ez.o_legendbox = OUTSIDE;
358                 else if (pol_word("none",2) == TRUE)
359                     ez.o_legendbox = NOLEGEND;
360                 else {
361                     gettext (str, MAXTOK);
362                     bad_option(str);
363                 }
364                 break;
365             case S_XLEGEND:
366                 if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
367                   {
368                     if (f >= 0.0 && f < 1.0) {
369                         ez.v_xlegend = f;
370                         ez.s_xlegend = TRUE;
371                     }
372                     else
373                       ez.s_xlegend = FALSE;
374                   }
375                 break;
376             case S_YLEGEND:
377                 if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
378                   {
379                     if (f >= 0.0 && f < 1.0) {
380                         ez.v_ylegend = f;
381                         ez.s_ylegend = TRUE;
382                     }
383                     else
384                       ez.s_ylegend = FALSE;
385                   }
386                 break;
387             case S_CURVES:
388                 if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE) {
389                     if (n < 1)
390                         n = 1;
391                     else if (n > MAXCURVES)
392                         n = MAXCURVES;
393                     if (modeinteract == TRUE) {
394                         curveinteract = n - 1;
395                         if (ez.o_unknowncurves == FALSE && ez.o_reqcurves < n)
396                              ez.o_reqcurves = n;
397                     } else {
398                         ezfree ();
399                         ez.o_reqcurves = n;
400                     }
401                 } else {
402                     if (pol_word ("unknown", 7) == TRUE)
403                         ez.o_unknowncurves = TRUE;
404                     else if (pol_word ("end", 3) == TRUE) {
405                         ez.o_unknowncurves = FALSE;
406                         ez.o_reqcurves = ez.i_numcurves;
407                         ez.i_plotimmediate = TRUE;
408                         ezplot (static_cast<double*>(NULL), static_cast<double*>(NULL), 0);
409                         ez.i_plotimmediate = FALSE;
410                     }
411                 }
412                 break;
413             case S_SYMBOL:
414                 if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE) {
415                     if (n > 0 && n <= MAXSYMBOL)
416                         ez.o_symbol = n;
417                     else
418                         ez.o_symbol = 1;
419                     if (modeinteract == TRUE && curveinteract >= 0)
420                         ez.curve[curveinteract].symbol = ez.o_symbol;
421                 } else {
422                     if (pol_word("every",5) == TRUE) {
423                         if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE) {
424                             if (n > 0)
425                                 ez.o_symfreq = n;
426                             else
427                                 ez.o_symfreq = 1;
428                             if (modeinteract == TRUE && curveinteract >= 0)
429                                 ez.curve[curveinteract].symfreq = ez.o_symfreq;
430                         }
431                     } else if (pol_word ("none",4) == TRUE) {
432                         ez.o_symbol = -1;
433                         if (modeinteract == TRUE && curveinteract >= 0)
434                             ez.curve[curveinteract].symbol = ez.o_symbol;
435                     }
436                 }
437                 break;
438             case S_XTICKS:
439                 if (pol_usertok(str,&lx) == FALSE)
440                     break;
441                 if (lx == S_ABOVE)
442                     ez.o_xticks = ABOVE;
443                 else if (lx == S_BELOW)
444                     ez.o_xticks = BELOW;
445                 else if (lx == S_NOLABEL)
446                     ez.o_xtlabel = FALSE;
447                 else if (lx == S_LABEL)
448                     ez.o_xtlabel = TRUE;
449                 else if (lx == S_MAJOR) {
450                      if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
451                         if (n > 1 && n < 100)
452                             ez.o_xmajortick = n;
453                 } else if (lx == S_MINOR)
454                      if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
455                         if (n >= 0 && n < 100)
456                             ez.o_xminortick = n;
457                 break;
458             case S_YTICKS:
459                 if (pol_usertok(str,&lx) == FALSE)
460                     break;
461                 if (lx == S_RIGHT)
462                     ez.o_yticks = RIGHT;
463                 else if (lx == S_LEFT)
464                     ez.o_yticks = LEFT;
465                 else if (lx == S_NOLABEL)
466                     ez.o_ytlabel = FALSE;
467                 else if (lx == S_LABEL)
468                     ez.o_ytlabel = TRUE;
469                 else if (lx == S_MAJOR) {
470                      if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
471                         if (n > 1 && n < 100)
472                             ez.o_ymajortick = n;
473                 } else if (lx == S_MINOR)
474              if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
475                         if (n >= 0 && n < 100)
476                             ez.o_yminortick = n;
477                 break;
478             case S_LXFRAC:
479                 if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE) {
480                     if (n >= 0) {
481                         ez.v_lxfrac = n;
482                         ez.s_lxfrac = TRUE;
483                     }
484                 } else
485                     ez.s_lxfrac = FALSE;
486                 break;
487             case S_LYFRAC:
488                 if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE) {
489                     if (n >= 0) {
490                         ez.v_lyfrac = n;
491                         ez.s_lyfrac = TRUE;
492                     }
493                 } else
494                     ez.s_lyfrac = FALSE;
495                 break;
496             case S_USTART:
497                 if (pol_word("no", 2) == TRUE)
498                     ez.o_ustart = FALSE;
499                 else
500                     ez.o_ustart = TRUE;
501                 break;
502             case S_UFINISH:
503                 if (pol_word("no", 2) == TRUE)
504                     ez.o_ufinish = FALSE;
505                 else
506                     ez.o_ufinish = TRUE;
507                 break;
508             default:
509                 fprintf (stderr, "Unimplemented EZPLOT command\n");
510                 break;
511         }
512
513         pol_reader ();
514         return (TRUE);
515 }
516
517 static void do_data (void)
518 {
519         double x[MAXPTS], y[MAXPTS], d;
520         int c, i;
521
522         printf ("Enter your data in free format\n");
523         printf ("Alternate X and Y coordinates\n");
524         printf ("Type ^Z (control Z) to terminate data entry\n");
525
526         pol_usefile (P_USE_FILE, "");
527         for (i = 0; i < MAXPTS; i++) {
528             if (pol_float (&d, TT_REAL, FALSE, 0, 0) == TRUE)
529                 x[i] = d;
530             else
531                 break;
532             if (pol_float (&d, TT_REAL, FALSE, 0, 0) == TRUE)
533                 y[i] = d;
534             else
535                 break;
536         }
537
538         if ((c = pol_inchar()) != EOF) {
539             ungetc (c, stdin);
540             printf("Error reading in points, read char %d, plotting %d points\n", c, i);
541         }
542         if (i > 0)
543             ezplot (x, y, i);
544         pol_closefile ();
545 }
546
547
548 static void do_help (void )
549 {
550         fputs ("EZSET Help: not available\n", stderr);
551 }
552
553
554 static void 
555 bad_option (char *opt)
556 {
557         fprintf(stderr,"%s is an INVALID option (sorry!)\n", opt);
558 }
559
560 /*----------------------------------------------------------------------*/
561 /*                      LEXIGRAPHICAL CODES                             */
562 /*----------------------------------------------------------------------*/
563
564 static struct key {
565         char *keyword;
566         int code;
567 } keytab[] = {
568         "solid",        S_SOLID,
569         "dash",         S_DASH,
570         "noline",       S_NOLINE,
571         "black",        S_BLACK,
572         "red",          S_RED,
573         "blue",         S_BLUE,
574         "green",        S_GREEN,
575         "pen",          S_PEN,
576         "symbol",       S_SYMBOL,
577 /*      "every",        S_EVERY,        */
578 /*      "none",         S_NONE,         */
579
580         "curves",       S_CURVES,
581         "curve",        S_CURVES,
582 /*      "unknown",      S_UNKNOWN,      */
583 /*      "end",          S_END,          */
584
585         "legend",       S_LEGEND,
586         "xlegend",      S_XLEGEND,
587         "ylegend",      S_YLEGEND,
588
589         "xlin",         S_XLIN,
590         "ylin",         S_YLIN,
591         "xlog",         S_XLOG,
592         "ylog",         S_YLOG,
593         "xlabel",       S_XLABEL,
594         "ylabel",       S_YLABEL,
595         "xlength",      S_XLENGTH,
596         "ylength",      S_YLENGTH,
597
598         "xticks",       S_XTICKS,
599         "yticks",       S_YTICKS,
600         "above",        S_ABOVE,
601         "label",        S_LABEL,
602         "below",        S_BELOW,
603         "nolabel",      S_NOLABEL,
604         "right",        S_RIGHT,
605         "left",         S_LEFT,
606
607         "xautoscale",   S_XAUTOSCALE,
608         "yautoscale",   S_YAUTOSCALE,
609         "xmin",         S_XMIN,
610         "ymin",         S_YMIN,
611         "xmax",         S_XMAX,
612         "ymax",         S_YMAX,
613         "lxfrac",       S_LXFRAC,
614         "lyfrac",       S_LYFRAC,
615         "xcross",       S_XCROSS,
616         "ycross",       S_YCROSS,
617         "noxaxis",      S_NOXAXIS,
618         "noyaxis",      S_NOYAXIS,
619         "xporigin",     S_XPORIGIN,
620         "yporigin",     S_YPORIGIN,
621         "title",        S_TITLE,
622         "xtitle",       S_XTITLE,
623         "ytitle",       S_YTITLE,
624
625         "replot",       S_REPLOT,
626         "clear",        S_CLEAR,
627         "store",        S_STORE,
628         "restore",      S_RESTORE,
629         "ustart",       S_USTART,
630         "ufinish",      S_UFINISH,
631         "amark",        S_AMARK,
632         "interactive",  S_INTERACTIVE,
633         "units",        S_UNITS,
634         "inches",       S_INCHES,
635         "user",         S_USER,
636
637         "data",         S_DATA,
638         "help",         S_HELP,
639         "exit",         S_EXIT,
640
641         "box",          S_BOX,
642         "nobox",        S_NOBOX,
643         "grid",         S_GRID,
644         "nogrid",       S_NOGRID,
645         "major",        S_MAJOR,
646         "minor",        S_MINOR,
647         "color",        S_COLOR,
648         "legendbox",    S_LEGENDBOX,
649
650         "epson",        S_EPSON,
651         "crt",          S_CRT,
652         "no",           S_NO,
653
654         "textsize",     S_TEXTSIZE,
655         "xbuf",         S_XBUF,
656         "ybuf",         S_YBUF,
657         "prtmode",      S_PRTMODE,
658 };
659
660 #define NKEYS  (sizeof(keytab) / sizeof(struct key))
661
662 static void initkw(void)
663 {
664         int i;
665
666         for (i = 0; i < NKEYS; i++)
667             if (pol_install(keytab[i].keyword, keytab[i].code) == FALSE)
668                 sys_error(ERR_SEVERE, "error installing ezset keywords [initkw]");
669 }