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