872d4e95cc5be57eb292baec38208ce807cdc11b
[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-2001 Kevin Rosenberg
8 **
9 **  $Id$
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 #include "ctsupport.h"
26 #include "ezplot.h"
27 #include "pol.h"
28
29
30 bool
31 EZPlot::ezset (const std::string& command)
32 {
33   return ezset (command.c_str());
34 }
35
36 bool
37 EZPlot::ezset (const char* const command)
38 {
39
40     return ezcmd (command);
41 }
42
43 bool
44 EZPlot::ezcmd (const char* const comm)
45 {
46   m_pol.usefile (POL::P_USE_STR, "");
47   m_pol.set_inputline (comm);
48
49   char str [POL::MAXTOK+1];
50   int code;
51   bool retval = true;
52   if (! m_pol.readUserToken (str, &code)) {
53     sys_error (ERR_WARNING, "Illegal EZSET command: %s", str);
54     m_pol.reader();
55     retval = false;
56   }
57   else
58     retval = do_cmd (code);
59
60   m_pol.closefile();                    /* close input string file */
61   return (retval);
62 }
63
64
65 bool
66 EZPlot::do_cmd (int lx)
67 {
68   char str [1024];
69   char strIn [1024];
70   int n;
71   double f;
72
73   switch (lx) {
74   case S_TEXTSIZE:
75     if (m_pol.readFloat (&f, POL::TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
76       if (f >= 0.0 && f <= 1.0) {
77         v_textsize = f;
78         s_textsize = TRUE;
79       } else
80         s_textsize = FALSE;
81     }
82     break;
83   case S_REPLOT:
84     plot (m_pSGP);
85     break;
86   case S_CLEAR:
87     clearCurves ();
88     break;
89   case S_TITLE:
90     m_pol.readText (strIn, sizeof(strIn));
91     c_title = strIn;
92     break;
93   case S_LEGEND:
94     m_pol.readText (strIn, sizeof(strIn));
95     if (m_iCurrentCurve >= 0)
96       setLegend (m_iCurrentCurve, strIn);
97     break;
98   case S_XLABEL:
99     m_pol.readText (strIn, sizeof(strIn));
100     c_xlabel = strIn;
101     break;
102   case S_YLABEL:
103     m_pol.readText (strIn, sizeof(strIn));
104     c_ylabel = strIn;
105     break;
106   case S_XCROSS:
107     if (m_pol.readFloat (&f, POL::TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
108       v_xcross = f;
109       s_xcross = TRUE;
110     } else
111       s_xcross = FALSE;
112     break;
113   case S_YCROSS:
114     if (m_pol.readFloat (&f, POL::TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
115       v_ycross = f;
116       s_ycross = TRUE;
117     } else
118       s_ycross = FALSE;
119     break;
120   case S_NOXAXIS:
121     o_xaxis = NOAXIS;
122     break;
123   case S_NOYAXIS:
124     o_yaxis = NOAXIS;
125     break;
126   case S_XLIN:
127     o_xaxis = LINEAR;
128     break;
129   case S_YLIN:
130     o_yaxis = LINEAR;
131     break;
132   case S_XLOG:
133     o_xaxis = LOG;
134     break;
135   case S_YLOG:
136     o_yaxis = LOG;
137     break;
138   case S_XAUTOSCALE:
139     s_xmin = FALSE;
140     s_xmax = FALSE;
141     break;
142   case S_YAUTOSCALE:
143     s_ymin = FALSE;
144     s_ymax = FALSE;
145     break;
146   case S_XMIN:
147     if (m_pol.readFloat (&f, POL::TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
148       v_xmin = f;
149       s_xmin = TRUE;
150     }
151     break;
152   case S_XMAX:
153     if (m_pol.readFloat (&f, POL::TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
154       v_xmax = f;
155       s_xmax = TRUE;
156     }
157     break;
158   case S_YMIN:
159     if (m_pol.readFloat (&f, POL::TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
160       v_ymin = f;
161       s_ymin = TRUE;
162     }
163     break;
164   case S_YMAX:
165     if (m_pol.readFloat (&f, POL::TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
166       v_ymax = f;
167       s_ymax = TRUE;
168     }
169     break;
170   case S_SOLID:
171     o_linestyle = SGP::LS_SOLID;
172     break;
173   case S_DASH:
174     int ls;
175     ls = SGP::LS_DASH1;
176     if (m_pol.readInteger (&n, POL::TT_REAL, FALSE, 0, 0) == TRUE) {
177       if (n == 1)
178         ls = SGP::LS_DASH1;
179       else if (n == 2)
180         ls = SGP::LS_DASH2;
181       else if (n == 3)
182         ls = SGP::LS_DASH3;
183       else if (n == 4)
184         ls = SGP::LS_DASH4;
185       else if (n == 5)
186         ls = SGP::LS_DOTTED;
187     }
188     if (m_iCurrentCurve < 0)
189       o_linestyle = ls;
190     else
191       setLinestyle (m_iCurrentCurve, ls);
192     break;
193   case S_NOLINE:
194     o_linestyle = SGP::LS_NOLINE;
195     break;
196   case S_PEN:
197   case S_COLOR:
198     if (m_pol.readInteger (&n, POL::TT_REAL, FALSE, 0, 0) == TRUE)
199     {
200       if (n >= 0) {
201         if (m_iCurrentCurve < 0)
202           o_color = n;
203         else
204           setColor (m_iCurrentCurve, n);
205       } else
206         bad_option("The color you picked");
207     }
208     break;
209   case S_BOX:
210     o_box = TRUE;
211     break;
212   case S_NOBOX:
213     o_box = FALSE;
214     break;
215   case S_GRID:
216     o_grid = TRUE;
217     break;
218   case S_NOGRID:
219     o_grid = FALSE;
220     break;
221   case S_XLENGTH:
222     if (m_pol.readFloat (&f, POL::TT_REAL, FALSE, 0.0, 0.0) == TRUE)
223       if (f > 0.0 && f <= 1.0)
224         o_xlength = f;
225       break;
226   case S_YLENGTH:
227     if (m_pol.readFloat (&f, POL::TT_REAL, FALSE, 0.0, 0.0) == TRUE)
228       if (f > 0.0 && f <= 1.0)
229         o_ylength = f;
230       break;
231   case S_XPORIGIN:
232     if (m_pol.readFloat (&f, POL::TT_REAL, FALSE, 0.0, 0.0) == TRUE)
233       if (f >= 0.0 && f < 1.0)
234         o_xporigin = f;
235       break;
236   case S_YPORIGIN:
237     if (m_pol.readFloat (&f, POL::TT_REAL, FALSE, 0.0, 0.0) == TRUE)
238       if (f >= 0.0 && f < 1.0)
239         o_yporigin = f;
240       break;
241   case S_TAG:
242     if (m_pol.readWord("no", 2) == TRUE)
243       o_tag = FALSE;
244     else if (m_pol.readWord("off", 2) == TRUE)
245       o_tag = FALSE;
246     else
247       o_tag = TRUE;
248     break;
249   case S_LEGENDBOX:
250     if (m_pol.readWord("inside", 2) == TRUE)
251       o_legendbox = INSIDE;
252     else if (m_pol.readWord("outside", 3) == TRUE)
253       o_legendbox = OUTSIDE;
254     else if (m_pol.readWord("none",2) == TRUE)
255       o_legendbox = NOLEGEND;
256     else {
257       m_pol.readText (str, POL::MAXTOK);
258       bad_option(str);
259     }
260     break;
261   case S_XLEGEND:
262     if (m_pol.readFloat (&f, POL::TT_REAL, FALSE, 0.0, 0.0) == TRUE)
263     {
264       if (f >= 0.0 && f < 1.0) {
265         v_xlegend = f;
266         s_xlegend = TRUE;
267       }
268       else
269         s_xlegend = FALSE;
270     }
271     break;
272   case S_YLEGEND:
273     if (m_pol.readFloat (&f, POL::TT_REAL, FALSE, 0.0, 0.0) == TRUE)
274     {
275       if (f >= 0.0 && f < 1.0) {
276         v_ylegend = f;
277         s_ylegend = TRUE;
278       }
279       else
280         s_ylegend = FALSE;
281     }
282     break;
283   case S_SYMBOL:
284     if (m_pol.readInteger (&n, POL::TT_REAL, FALSE, 0, 0) == TRUE) {
285       if (n > 0 && n <= MAXSYMBOL) {
286         if (m_iCurrentCurve < 0)
287           o_symbol = n;
288         else
289           setSymbol (m_iCurrentCurve, n);
290       }
291     } else {
292       if (m_pol.readWord("every",5) == TRUE) {
293         if (m_pol.readInteger (&n, POL::TT_REAL, FALSE, 0, 0) == TRUE) {
294           int sym = 1;
295           if (n > 0)
296             sym = n;
297           if (m_iCurrentCurve < 0)
298             o_symfreq = sym;
299           else
300             setSymbolFreq (m_iCurrentCurve, sym);
301         }
302       } else if (m_pol.readWord ("none",4) == TRUE) {
303         o_symbol = -1;
304       }
305     }
306     break;
307   case S_CURVE:
308     if (m_pol.readInteger (&n, POL::TT_REAL, FALSE, 0, 0) == TRUE) {
309       if (n > 0)
310         m_iCurrentCurve = n - 1;
311     } else {
312       if (m_pol.readWord ("all",3) == TRUE)
313         m_iCurrentCurve = -1;
314     }
315     break;
316   case S_XTICKS:
317     if (m_pol.readUserToken(str,&lx) == FALSE)
318       break;
319     if (lx == S_ABOVE)
320       o_xticks = ABOVE;
321     else if (lx == S_BELOW)
322       o_xticks = BELOW;
323     else if (lx == S_NOLABEL)
324       o_xtlabel = FALSE;
325     else if (lx == S_LABEL)
326       o_xtlabel = TRUE;
327     else if (lx == S_MAJOR) {
328       if (m_pol.readInteger (&n, POL::TT_REAL, FALSE, 0, 0) == TRUE)
329         if (n > 1 && n < 100)
330           o_xmajortick = n;
331     } else if (lx == S_MINOR)
332       if (m_pol.readInteger (&n, POL::TT_REAL, FALSE, 0, 0) == TRUE)
333         if (n >= 0 && n < 100)
334           o_xminortick = n;
335         break;
336   case S_YTICKS:
337     if (m_pol.readUserToken(str,&lx) == FALSE)
338       break;
339     if (lx == S_RIGHT)
340       o_yticks = RIGHT;
341     else if (lx == S_LEFT)
342       o_yticks = LEFT;
343     else if (lx == S_NOLABEL)
344       o_ytlabel = FALSE;
345     else if (lx == S_LABEL)
346       o_ytlabel = TRUE;
347     else if (lx == S_MAJOR) {
348       if (m_pol.readInteger (&n, POL::TT_REAL, FALSE, 0, 0) == TRUE)
349         if (n > 1 && n < 100)
350           o_ymajortick = n;
351     } else if (lx == S_MINOR)
352       if (m_pol.readInteger (&n, POL::TT_REAL, FALSE, 0, 0) == TRUE)
353         if (n >= 0 && n < 100)
354           o_yminortick = n;
355         break;
356   case S_LXFRAC:
357     if (m_pol.readInteger (&n, POL::TT_REAL, FALSE, 0, 0) == TRUE) {
358       if (n >= 0) {
359         v_lxfrac = n;
360         s_lxfrac = TRUE;
361       }
362     } else
363       s_lxfrac = FALSE;
364     break;
365   case S_LYFRAC:
366     if (m_pol.readInteger (&n, POL::TT_REAL, FALSE, 0, 0) == TRUE) {
367       if (n >= 0) {
368         v_lyfrac = n;
369         s_lyfrac = TRUE;
370       }
371     } else
372       s_lyfrac = FALSE;
373     break;
374     break;
375   default:
376     fprintf (stderr, "Unimplemented EZPLOT command\n");
377     break;
378   }
379
380   m_pol.reader ();
381   return (true);
382 }
383
384
385
386 void
387 EZPlot::bad_option (char *opt)
388 {
389   sys_error (ERR_WARNING, "INVALID option: %s", opt);
390 }
391
392
393 //----------------------------------------------------------------------
394 //                      KEYWORDS / CODES TABLE
395 //----------------------------------------------------------------------
396 const struct KeywordCodeTable EZPlot::m_sKeywords[] =
397 {
398   {"solid",     S_SOLID},
399   {"dash", S_DASH},
400   {"curve", S_CURVE},
401   {"noline",    S_NOLINE},
402   {"black",     S_BLACK},
403   {"red",               S_RED},
404   {"blue",              S_BLUE},
405   {"green",     S_GREEN},
406   {"pen",               S_PEN},
407   {"symbol",    S_SYMBOL},
408   {"every",     S_EVERY},
409   {"none",              S_NONE},
410   {"legend",    S_LEGEND},
411   {"xlegend",   S_XLEGEND},
412   {"ylegend",   S_YLEGEND},
413
414   {"xlin",              S_XLIN},
415   {"ylin",              S_YLIN},
416   {"xlog",              S_XLOG},
417   {"ylog",              S_YLOG},
418   {"xlabel",    S_XLABEL},
419   {"ylabel",    S_YLABEL},
420   {"xlength",   S_XLENGTH},
421   {"ylength",   S_YLENGTH},
422
423   {"xticks",    S_XTICKS},
424   {"yticks",    S_YTICKS},
425   {"above",     S_ABOVE},
426   {"label",     S_LABEL},
427   {"below",     S_BELOW},
428   {"nolabel",   S_NOLABEL},
429   {"right",     S_RIGHT},
430   {"left",              S_LEFT},
431
432   {"xautoscale",        S_XAUTOSCALE},
433   {"yautoscale",        S_YAUTOSCALE},
434   {"xmin",              S_XMIN},
435   {"ymin",              S_YMIN},
436   {"xmax",              S_XMAX},
437   {"ymax",              S_YMAX},
438   {"lxfrac",    S_LXFRAC},
439   {"lyfrac",    S_LYFRAC},
440   {"xcross",    S_XCROSS},
441   {"ycross",    S_YCROSS},
442   {"noxaxis",   S_NOXAXIS},
443   {"noyaxis",   S_NOYAXIS},
444   {"xporigin",  S_XPORIGIN},
445   {"yporigin",  S_YPORIGIN},
446   {"title",     S_TITLE},
447   {"xtitle",    S_XTITLE},
448   {"ytitle",    S_YTITLE},
449
450   {"replot",    S_REPLOT},
451   {"clear",     S_CLEAR},
452   {"store",     S_STORE},
453   {"restore",   S_RESTORE},
454   {"amark",     S_AMARK},
455   {"units",     S_UNITS},
456   {"inches",    S_INCHES},
457   {"user",              S_USER},
458
459   {"data",              S_DATA},
460   {"help",              S_HELP},
461   {"exit",              S_EXIT},
462
463   {"box",               S_BOX},
464   {"nobox",     S_NOBOX},
465   {"grid",              S_GRID},
466   {"nogrid",    S_NOGRID},
467   {"major",     S_MAJOR},
468   {"minor",     S_MINOR},
469   {"color",     S_COLOR},
470   {"legendbox", S_LEGENDBOX},
471
472   {"no",                S_NO},
473
474   {"textsize",  S_TEXTSIZE},
475 };
476
477 const int EZPlot::NKEYS = (sizeof(EZPlot::m_sKeywords) / sizeof (struct KeywordCodeTable));
478
479 void
480 EZPlot::initKeywords ()
481 {
482   for (int i = 0; i < NKEYS; i++)
483     m_pol.addKeyword (m_sKeywords[i].keyword, m_sKeywords [i].code);
484 }