Imported Upstream version 2.9.0
[debian/cc1111] / sim / ucsim / option.cc
1 /*
2  * Simulator of microcontrollers (option.cc)
3  *
4  * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
5  * 
6  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
7  *
8  */
9
10 /*
11   This file is part of microcontroller simulator: ucsim.
12
13   UCSIM is free software; you can redistribute it and/or modify
14   it under the terms of the GNU General Public License as published by
15   the Free Software Foundation; either version 2 of the License, or
16   (at your option) any later version.
17   
18   UCSIM is distributed in the hope that it will be useful,
19   but WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21   GNU General Public License for more details.
22   
23   You should have received a copy of the GNU General Public License
24   along with UCSIM; see the file COPYING.  If not, write to the Free
25   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26   02111-1307, USA.
27 */
28 /*@1@*/
29
30 #include "ddconfig.h"
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <ctype.h>
35 #include "i_string.h"
36
37   // local, prj
38 #include "stypes.h"
39 #include "optioncl.h"
40 #include "globals.h"
41 #include "utils.h"
42
43   // sim.src
44 #include "simcl.h"
45
46
47 /*struct id_element option_type_names[]= {
48   { non_opt     , "non" },
49   { integer_opt , "integer" },
50   { float_opt   , "float" },
51   { bool_opt    , "boolean" },
52   { string_opt  , "string" },
53   { pointer_opt , "pointer" },
54   { 0, 0 }
55   };*/
56
57 /*
58  * Base class for option's objects
59  *____________________________________________________________________________
60  *
61  */
62
63 cl_option::cl_option(class cl_base *the_creator, const char *aname, const char *Ihelp):
64   cl_base()
65 {
66   creator= the_creator;
67   set_name(aname);
68   help= strdup(Ihelp);
69   char *s= (char*)malloc(strlen(aname)+100);
70   sprintf(s, "users of option \"%s\"", aname);
71   users= new cl_list(2, 2, s);
72   free(s);
73   memset(&value, 0, sizeof(value));
74   show();
75 }
76
77 class cl_option &
78 cl_option::operator=(class cl_option &o)
79 {
80   //memcpy(&value, &(o.value), sizeof(union option_value));
81   //fprintf(stderr,"opt%p\"%s\"=%p\"%s\"\nold=%p\n",this,object_name(this),&o,object_name(&o),value.sval);
82   value= o.value;
83   //fprintf(stderr,"new=%p\n",value.sval);
84   inform_users();
85   return(*this);
86 }
87
88 cl_option::~cl_option(void)
89 {
90   users->disconn_all();
91   delete users;
92   free(help);
93 }
94
95 void
96 cl_option::pre_remove(void)
97 {
98   int i;
99
100   for (i= 0; i < users->count; i++)
101     {
102       class cl_optref *user= (class cl_optref *)(users->at(i));
103       user->option_removing();
104     }
105 }
106
107 void
108 cl_option::new_reference(class cl_optref *ref)
109 {
110   users->add(ref);
111 }
112
113 void
114 cl_option::del_reference(class cl_optref *ref)
115 {
116   users->disconn(ref);
117 }
118
119 void
120 cl_option::inform_users(void)
121 {
122   int i;
123
124   for (i= 0; i < users->count; i++)
125     {
126       class cl_optref *user= (class cl_optref *)(users->at(i));
127       //fprintf(stderr,"%p\"%s\" informs user %p\"%s\"\n",this,object_name(this),user,object_name(user));
128       user->option_changed();
129     }
130 }
131
132
133 void
134 cl_option::get_value(bool *val)
135 {
136   if (val)
137     *val= value.bval;
138 }
139
140 void
141 cl_option::set_value(bool opt)
142 {
143   value.bval= opt;
144   inform_users();
145 }
146
147
148 void
149 cl_option::get_value(char **val)
150 {
151   if (val)
152     *val= value.sval;
153 }
154
155 void
156 cl_option::set_value(char *opt)
157 {
158   //fprintf(stderr,"set_string_value (%s) to %p\"%s\"\n",opt,this,object_name(this));
159   //fprintf(stderr,"old value=%p\"%s\"\n",value.sval,value.sval);
160   if (value.sval)
161     free(value.sval);
162   if (opt &&
163       *opt)
164     value.sval= strdup(opt);
165   else
166     value.sval= strdup("");
167   //fprintf(stderr,"new value=%p\"%s\"\n",value.sval,value.sval);
168   inform_users();
169 }
170
171
172 void
173 cl_option::get_value(void **val)
174 {
175   if (val)
176     *val= value.pval;
177 }
178
179 void
180 cl_option::set_value(void *opt)
181 {
182   value.pval= opt;
183   inform_users();
184 }
185
186
187 void
188 cl_option::get_value(long *val)
189 {
190   if (val)
191     *val= value.ival;
192 }
193
194 void
195 cl_option::set_value(long opt)
196 {
197   value.ival= opt;
198   inform_users();
199 }
200
201
202 void
203 cl_option::get_value(double *val)
204 {
205   if (val)
206     *val= value.fval;
207 }
208
209 void
210 cl_option::set_value(double opt)
211 {
212   value.fval= opt;
213   inform_users();
214 }
215
216
217 /*
218  * List of options
219  */
220
221 const void *
222 cl_options::key_of(void *item)
223 {
224   return(((class cl_base *)item)->get_name());
225 }
226
227 int
228 cl_options::compare(const void *key1, const void *key2)
229 {
230   return(strcmp(static_cast<const char *>(key1), static_cast<const char *>(key2)));
231 }
232
233 void
234 cl_options::new_option(class cl_option *opt)
235 {
236   add(opt);
237 }
238
239 void
240 cl_options::del_option(class cl_option *opt)
241 {
242   opt->pre_remove();
243   disconn(opt);
244   delete opt;
245 }
246
247 class cl_option *
248 cl_options::get_option(const char *the_name)
249 {
250   t_index idx;
251
252   if (search(the_name, idx))
253     return((class cl_option *)(at(idx)));
254   return(0);
255 }
256
257 class cl_option *
258 cl_options::get_option(const char *the_name, class cl_base *creator)
259 {
260   t_index idx;
261   class cl_option *o;
262
263   if (!search(the_name, idx))
264     return(0);
265   if (idx > 0)
266     {
267       idx--;
268       o= (class cl_option *)(at(idx));
269       while (compare(the_name, key_of(o)) == 0 &&
270              idx > 0)
271         {
272           idx--;
273           o= (class cl_option *)(at(idx));
274         }
275       if (compare(the_name, key_of(o)) != 0)
276         idx++;
277     }
278   o= (class cl_option *)(at(idx));
279   while (compare(the_name, key_of(o)) == 0 &&
280          o->get_creator() != creator &&
281          idx < count)
282     {
283       idx++;
284       o= (class cl_option *)(at(idx));
285       if (compare(the_name, key_of(o)) == 0 &&
286           o->get_creator() == creator)
287         return(o);
288     }
289   if (compare(the_name, key_of(o)) == 0 &&
290       o->get_creator() == creator)
291     return(o);
292   return(0);
293 }
294
295 class cl_option *
296 cl_options::get_option(const char *the_name, char *creator)
297 {
298   t_index idx;
299   class cl_option *o;
300
301   if (!search(the_name, idx))
302     return(0);
303   if (idx > 0)
304     {
305       idx--;
306       o= (class cl_option *)(at(idx));
307       while (compare(the_name, key_of(o)) == 0 &&
308              idx > 0)
309         {
310           idx--;
311           o= (class cl_option *)(at(idx));
312         }
313       if (compare(the_name, key_of(o)) != 0)
314         idx++;
315     }
316   o= (class cl_option *)(at(idx));
317   while (compare(the_name, key_of(o)) == 0 &&
318          strcmp(object_name(o->get_creator()), creator) != 0 &&
319          idx < count)
320     {
321       idx++;
322       o= (class cl_option *)(at(idx));
323       if (compare(the_name, key_of(o)) == 0 &&
324           strcmp(object_name(o->get_creator()), creator) == 0)
325         return(o);
326     }
327   if (compare(the_name, key_of(o)) == 0 &&
328       strcmp(object_name(o->get_creator()), creator) == 0)
329     return(o);
330   return(0);
331 }
332
333 class cl_option *
334 cl_options::get_option(int idx)
335 {
336   if (idx >= count)
337     return(0);
338   return((class cl_option *)(at(idx)));
339 }
340
341 int
342 cl_options::nuof_options(char *the_name)
343 {
344   int i, n= 0;
345
346   for (i= 0; i < count; i++)
347     {
348       class cl_option *o= (class cl_option *)(at(i));
349       if (strcmp(the_name, o->get_name()) == 0)
350         n++;
351     }
352   return(n);
353 }
354
355 int
356 cl_options::nuof_options(char *the_name, char *creator)
357 {
358   int i, n= 0;
359
360   for (i= 0; i < count; i++)
361     {
362       class cl_option *o= (class cl_option *)(at(i));
363       if (strcmp(the_name, o->get_name()) == 0 &&
364           strcmp(creator, object_name(o->get_creator())) == 0)
365         n++;
366     }
367   return(n);
368 }
369
370 class cl_option *
371 cl_options::set_value(const char *the_name, cl_base *creator, bool value)
372 {
373   class cl_option *o= get_option(the_name, creator);
374
375   if (o)
376     o->set_value(value);
377   return(o);
378 }
379
380 class cl_option *
381 cl_options::set_value(const char *the_name, cl_base *creator, char *value)
382 {
383   class cl_option *o= get_option(the_name, creator);
384
385   if (o)
386     o->set_value(value);
387   return(o);
388 }
389
390 class cl_option *
391 cl_options::set_value(const char *the_name, cl_base *creator, void *value)
392 {
393   class cl_option *o= get_option(the_name, creator);
394
395   if (o)
396     o->set_value(value);
397   return(o);
398 }
399
400 class cl_option *
401 cl_options::set_value(const char *the_name, cl_base *creator, long value)
402 {
403   class cl_option *o= get_option(the_name, creator);
404
405   if (o)
406     o->set_value(value);
407   return(o);
408 }
409
410 class cl_option *
411 cl_options::set_value(const char *the_name, cl_base *creator, double value)
412 {
413   class cl_option *o= get_option(the_name, creator);
414
415   if (o)
416     o->set_value(value);
417   return(o);
418 }
419
420
421 /*
422  * Reference to an option
423  */
424
425 cl_optref::cl_optref(class cl_base *the_owner)
426 {
427   option =0;
428   owner= the_owner;
429 }
430
431 cl_optref::cl_optref(class cl_base *the_owner, class cl_option *new_option)
432 {
433   owner= the_owner;
434   option= new_option;
435   application->options->new_option(option);
436   if (option)
437     {
438       option->new_reference(this);
439       set_name(option->get_name());
440     }
441 }
442
443 cl_optref::~cl_optref(void)
444 {
445   if (option)
446     {
447       option->del_reference(this);
448       if (option->get_creator() == owner)
449         application->options->del_option(option);
450     }
451 }
452
453 class cl_option *
454 cl_optref::create(class cl_base *creator,
455                   enum option_type type,
456                   const char *the_name, const char *help)
457 {
458   if (option)
459     option->del_reference(this);
460   switch (type)
461     {
462     case non_opt:
463       option= 0;
464       break;
465     case integer_opt:
466       option= new cl_number_option(creator, the_name, help);
467       break;
468     case float_opt:
469       option= new cl_float_option(creator, the_name, help);
470       break;
471     case bool_opt:
472       option= new cl_bool_option(creator, the_name, help);
473       break;
474     case string_opt:
475       option= new cl_string_option(creator, the_name, help);
476       break;
477     case pointer_opt:
478       option= new cl_pointer_option(creator, the_name, help);
479       break;
480     default:
481       option= 0;
482       break;
483     }
484   if (option)
485     {
486       application->options->new_option(option);
487       option->new_reference(this);
488       set_name(option->get_name());
489     }
490   
491   return(option);
492 }
493
494 void
495 cl_optref::default_option(const char *the_name)
496 {
497   class cl_option *o= application->options->get_option(the_name, application);
498
499   if (o &&
500       option)
501     {
502       //memcpy(option->get_value(), o->get_value(), sizeof(union option_value));
503       *option= *o;
504       option->inform_users();
505     }
506   /*else
507     fprintf(stderr,"can not set opt from default, option=%p, o=%p\n",option,o);*/
508 }
509
510 class cl_option *
511 cl_optref::use(void)
512 {
513   if (option)
514     {
515       option->del_reference(this);
516       option->new_reference(this);
517     }
518   return(option);
519 }
520
521 class cl_option *
522 cl_optref::use(const char *the_name)
523 {
524   if (option)
525     option->del_reference(this);
526   option= application->options->get_option(the_name);
527   if (option)
528     {
529       option->new_reference(this);
530       set_name(option->get_name());
531     }
532   return(option);
533 }
534
535 void
536 cl_optref::option_removing(void)
537 {
538   option= 0;
539 }
540
541 bool
542 cl_optref::get_value(bool)
543 {
544   if (!option)
545     {
546       fprintf(stderr, "Warning: \"%s\" is sdereferencing a non-existent "
547               "bool option: %s\n", object_name(owner), get_name());
548       return(DD_FALSE);
549     }
550   else
551     {
552       bool v;
553       option->get_value(&v);
554       return(v);
555     }
556 }
557
558 char *
559 cl_optref::get_value(const char *)
560 {
561   if (!option)
562     {
563       fprintf(stderr, "Warning: \"%s\" is sdereferencing a non-existent "
564               "string option: %s\n", object_name(owner), get_name());
565       return(0);
566     }
567   else
568     {
569       char *s= 0;
570       option->get_value(&s);
571       return(s);
572     }
573 }
574
575 void *
576 cl_optref::get_value(void *)
577 {
578   if (!option)
579     {
580       fprintf(stderr, "Warning: \"%s\" is sdereferencing a non-existent "
581               "pointer option: %s\n", object_name(owner), get_name());
582       return(NIL);
583     }
584   else
585     {
586       void *p= NIL;
587       option->get_value(&p);
588       return(p);
589     }
590 }
591
592 long
593 cl_optref::get_value(long)
594 {
595   if (!option)
596     {
597       fprintf(stderr, "Warning: \"%s\" is sdereferencing a non-existent "
598               "number option: %s\n", object_name(owner), get_name());
599       return(0);
600     }
601   else
602     {
603       long l= 0;
604       option->get_value(&l);
605       return(l);
606     }
607 }
608
609 double
610 cl_optref::get_value(double)
611 {
612   if (!option)
613     {
614       fprintf(stderr, "Warning: \"%s\" is sdereferencing a non-existent "
615               "float option: %s\n", object_name(owner), get_name());
616       return(0);
617     }
618   else
619     {
620       double d= 0;
621       option->get_value(&d);
622       return(d);
623     }
624 }
625
626
627 /*
628  * BOOL type of option
629  *____________________________________________________________________________
630  *
631  */
632
633 cl_bool_option::cl_bool_option(class cl_base *the_creator,
634                                const char *aname, const char *Ihelp):
635   cl_option(the_creator, aname, Ihelp)
636 {}
637
638 void
639 cl_bool_option::print(class cl_console_base *con)
640 {
641   if (/**(bool *)option*/value.bval)
642     con->dd_printf("TRUE");
643   else
644     con->dd_printf("FALSE");
645 }
646
647 void
648 cl_bool_option::set_value(char *s)
649 {
650   char c;
651
652   if (s)
653     {
654       c= toupper(*s);
655       if (c == '1' ||
656           c == 'T' ||
657           c == 'Y')
658         /**(bool *)option=*/ value.bval= DD_TRUE;
659       else
660         /**(bool *)option=*/ value.bval= DD_FALSE;
661     }
662   inform_users();
663 }
664
665
666 /*
667  * STRING type of option
668  *____________________________________________________________________________
669  *
670  */
671
672 cl_string_option::cl_string_option(class cl_base *the_creator,
673                                    const char *aname, const char *Ihelp):
674   cl_option(the_creator, aname, Ihelp)
675 {}
676
677 class cl_option &
678 cl_string_option::operator=(class cl_option &o)
679 {
680   //fprintf(stderr,"string=otheropt%p\"%s\"\nold=%p\"%s\"\n",&o,object_name(&o),value.sval,value.sval);
681   set_value((o.get_value())->sval);
682   //fprintf(stderr,"new=%p\"%s\"\n",value.sval,value.sval);
683   return(*this);
684 }
685
686 void
687 cl_string_option::print(class cl_console_base *con)
688 {
689   if (/**(bool *)option*/value.sval)
690     con->dd_printf("\"%s\"", value.sval);
691   else
692     con->dd_printf("(null)");
693 }
694
695
696 /*
697  * PONITER type of option
698  *____________________________________________________________________________
699  *
700  */
701
702 cl_pointer_option::cl_pointer_option(class cl_base *the_creator,
703                                      const char *aname, const char *Ihelp):
704   cl_option(the_creator, aname, Ihelp)
705 {}
706
707 class cl_option &
708 cl_pointer_option::operator=(class cl_option &o)
709 {
710   set_value((o.get_value())->pval);
711   return(*this);
712 }
713
714 void
715 cl_pointer_option::print(class cl_console_base *con)
716 {
717   if (value.pval)
718     con->dd_printf("\"%p\"", value.pval);
719   else
720     con->dd_printf("(null)");
721 }
722
723
724 /*
725  * Debug on console
726  */
727 /*
728 cl_cons_debug_opt::cl_cons_debug_opt(class cl_app *the_app,
729                                      char *Iid,
730                                      char *Ihelp):
731   cl_option(0, Iid, Ihelp)
732 {
733   app= the_app;
734 }
735
736 void
737 cl_cons_debug_opt::print(class cl_console_base *con)
738 {
739   if (con->flags & CONS_DEBUG)
740     con->dd_printf("TRUE");
741   else
742     con->dd_printf("FALSE");
743 }
744
745 void
746 cl_cons_debug_opt::get_value(bool *val)
747 {
748   if (val)
749     *val= app->get_commander()->actual_console?
750       (app->get_commander()->actual_console->flags & CONS_DEBUG):0;
751 }
752
753 void
754 cl_cons_debug_opt::set_value(bool opt)
755 {
756   if (app->get_commander()->actual_console)
757     {
758       if (opt)
759         app->get_commander()->actual_console->flags|= CONS_DEBUG;
760       else
761         app->get_commander()->actual_console->flags&= ~CONS_DEBUG;
762     }
763   inform_users();
764 }
765
766 void
767 cl_cons_debug_opt::set_value(char *s)
768 {
769   char c;
770
771   if (s &&
772       app->get_commander()->actual_console)
773     {
774       c= toupper(*s);
775       if (c == '1' ||
776           c == 'T' ||
777           c == 'Y')
778         set_value(1);
779       else
780         set_value(0);
781     }
782 }
783 */
784
785 /*
786  * NUMBER type of option
787  *____________________________________________________________________________
788  *
789  */
790
791 cl_number_option::cl_number_option(class cl_base *the_creator,
792                                    const char *aname, const char *Ihelp):
793   cl_option(the_creator, aname, Ihelp)
794 {}
795
796 void
797 cl_number_option::print(class cl_console_base *con)
798 {
799   con->dd_printf("%ld", value.ival);
800 }
801
802 void
803 cl_number_option::set_value(char *s)
804 {
805   if (s)
806     value.ival= strtol(s, NIL, 0);
807   inform_users();
808 }
809
810
811 /*
812  * FLOAT type of option
813  *____________________________________________________________________________
814  *
815  */
816
817 cl_float_option::cl_float_option(class cl_base *the_creator,
818                                  const char *aname, const char *Ihelp):
819   cl_option(the_creator, aname, Ihelp)
820 {}
821
822 void
823 cl_float_option::print(class cl_console_base *con)
824 {
825   con->dd_printf("%.3f", value.fval);
826 }
827
828 void
829 cl_float_option::set_value(char *s)
830 {
831   if (s)
832     value.fval= strtod(s, NIL);
833   inform_users();
834 }
835
836
837 /* End of option.cc */