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