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