diff options
| author | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
|---|---|---|
| committer | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
| commit | 268a53de823a6750d6256ee1fb1e7707b4b45740 (patch) | |
| tree | 42c1799a9a82b2f7d9790ee9fe181d72a7274751 /sim/ucsim/option.cc | |
| download | sdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz | |
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'sim/ucsim/option.cc')
| -rw-r--r-- | sim/ucsim/option.cc | 852 |
1 files changed, 852 insertions, 0 deletions
diff --git a/sim/ucsim/option.cc b/sim/ucsim/option.cc new file mode 100644 index 0000000..208ba53 --- /dev/null +++ b/sim/ucsim/option.cc @@ -0,0 +1,852 @@ +/* + * Simulator of microcontrollers (option.cc) + * + * Copyright (C) 1997,16 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +UCSIM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +#include "ddconfig.h" + +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include "i_string.h" + + // local, prj +#include "stypes.h" +#include "optioncl.h" +#include "globals.h" +#include "utils.h" + + // sim.src +#include "simcl.h" + + +/*struct id_element option_type_names[]= { + { non_opt , "non" }, + { integer_opt , "integer" }, + { float_opt , "float" }, + { bool_opt , "boolean" }, + { string_opt , "string" }, + { pointer_opt , "pointer" }, + { 0, 0 } + };*/ + +/* + * Base class for option's objects + *____________________________________________________________________________ + * + */ + +cl_option::cl_option(class cl_base *the_creator, const char *aname, const char *Ihelp): + cl_base() +{ + creator= the_creator; + set_name(aname); + help= strdup(Ihelp); + char *s= (char*)malloc(strlen(aname)+100); + sprintf(s, "users of option \"%s\"", aname); + users= new cl_list(2, 2, s); + free(s); + memset(&value, 0, sizeof(value)); + show(); +} + +class cl_option & +cl_option::operator=(class cl_option &o) +{ + //memcpy(&value, &(o.value), sizeof(union option_value)); + //fprintf(stderr,"opt%p\"%s\"=%p\"%s\"\nold=%p\n",this,object_name(this),&o,object_name(&o),value.sval); + value= o.value; + //fprintf(stderr,"new=%p\n",value.sval); + inform_users(); + return(*this); +} + +cl_option::~cl_option(void) +{ + users->disconn_all(); + delete users; + free(help); +} + +void +cl_option::pre_remove(void) +{ + int i; + + for (i= 0; i < users->count; i++) + { + class cl_optref *user= (class cl_optref *)(users->at(i)); + user->option_removing(); + } +} + +void +cl_option::new_reference(class cl_optref *ref) +{ + users->add(ref); +} + +void +cl_option::del_reference(class cl_optref *ref) +{ + users->disconn(ref); +} + +void +cl_option::inform_users(void) +{ + int i; + + for (i= 0; i < users->count; i++) + { + class cl_optref *user= (class cl_optref *)(users->at(i)); + //fprintf(stderr,"%p\"%s\" informs user %p\"%s\"\n",this,object_name(this),user,object_name(user)); + user->option_changed(); + } +} + + +void +cl_option::get_value(bool *val) +{ + if (val) + *val= value.bval; +} + +void +cl_option::set_value(bool opt) +{ + value.bval= opt; + inform_users(); +} + + +void +cl_option::get_value(char **val) +{ + if (val) + { + *val= value.sval; + } +} + +void +cl_option::set_value(char *opt) +{ + //fprintf(stderr,"set_string_value (%s) to %p\"%s\"\n",opt,this,object_name(this)); + //fprintf(stderr,"old value=%p\"%s\"\n",value.sval,value.sval); + if (value.sval) + free(value.sval); + if (opt && + *opt) + value.sval= strdup(opt); + else + value.sval= strdup(""); + //fprintf(stderr,"new value=%p\"%s\"\n",value.sval,value.sval); + inform_users(); +} + +void +cl_option::set_value(const char *opt) +{ + set_value(cchars(opt)); +} + +void +cl_option::get_value(void **val) +{ + if (val) + *val= value.pval; +} + +void +cl_option::set_value(void *opt) +{ + value.pval= opt; + inform_users(); +} + + +void +cl_option::get_value(long *val) +{ + if (val) + *val= value.ival; +} + +void +cl_option::set_value(long opt) +{ + value.ival= opt; + inform_users(); +} + + +void +cl_option::get_value(double *val) +{ + if (val) + *val= value.fval; +} + +void +cl_option::set_value(double opt) +{ + value.fval= opt; + inform_users(); +} + + +/* + * List of options + */ + +void * +cl_options::key_of(void *item) +{ + return (void*)(((class cl_base *)item)->get_name()); +} + +int +cl_options::compare(void *key1, void *key2) +{ + //class cl_option *k1, *k2; + int i; + char *k1, *k2; + + k1= /*(class cl_option *)*/(char *)key1; + k2= /*(class cl_option *)*/(char *)key2; + if ((i= strcmp(k1, k2)) != 0) + return(i); + return(i); +} + +void +cl_options::new_option(class cl_option *opt) +{ + add(opt); +} + +void +cl_options::del_option(class cl_option *opt) +{ + opt->pre_remove(); + disconn(opt); + delete opt; +} + +class cl_option * +cl_options::get_option(const char *the_name) +{ + t_index idx; + + if (search((void*)the_name, idx)) + return((class cl_option *)(at(idx))); + return(0); +} + +class cl_option * +cl_options::get_option(const char *the_name, class cl_base *creator) +{ + t_index idx; + class cl_option *o; + + if (!search((void*)the_name, idx)) + return(0); + if (idx > 0) + { + idx--; + o= (class cl_option *)(at(idx)); + while (compare((void*)the_name, key_of(o)) == 0 && + idx > 0) + { + idx--; + o= (class cl_option *)(at(idx)); + } + if (compare((void*)the_name, key_of(o)) != 0) + idx++; + } + o= (class cl_option *)(at(idx)); + while (compare((void*)the_name, key_of(o)) == 0 && + o->get_creator() != creator && + idx < count) + { + idx++; + o= (class cl_option *)(at(idx)); + if (compare((void*)the_name, key_of(o)) == 0 && + o->get_creator() == creator) + return(o); + } + if (compare((void*)the_name, key_of(o)) == 0 && + o->get_creator() == creator) + return(o); + return(0); +} + +class cl_option * +cl_options::get_option(const char *the_name, char *creator) +{ + t_index idx; + class cl_option *o; + + if (!search((void*)the_name, idx)) + return(0); + if (idx > 0) + { + idx--; + o= (class cl_option *)(at(idx)); + while (compare((void*)the_name, key_of(o)) == 0 && + idx > 0) + { + idx--; + o= (class cl_option *)(at(idx)); + } + if (compare((void*)the_name, key_of(o)) != 0) + idx++; + } + o= (class cl_option *)(at(idx)); + while (compare((void*)the_name, key_of(o)) == 0 && + strcmp(object_name(o->get_creator()), creator) != 0 && + idx < count) + { + idx++; + o= (class cl_option *)(at(idx)); + if (compare((void*)the_name, key_of(o)) == 0 && + strcmp(object_name(o->get_creator()), creator) == 0) + return(o); + } + if (compare((void*)the_name, key_of(o)) == 0 && + strcmp(object_name(o->get_creator()), creator) == 0) + return(o); + return(0); +} + +class cl_option * +cl_options::get_option(int idx) +{ + if (idx >= count) + return(0); + return((class cl_option *)(at(idx))); +} + +int +cl_options::nuof_options(char *the_name) +{ + int i, n= 0; + + for (i= 0; i < count; i++) + { + class cl_option *o= (class cl_option *)(at(i)); + if (strcmp(the_name, o->get_name()) == 0) + n++; + } + return(n); +} + +int +cl_options::nuof_options(char *the_name, char *creator) +{ + int i, n= 0; + + for (i= 0; i < count; i++) + { + class cl_option *o= (class cl_option *)(at(i)); + if (strcmp(the_name, o->get_name()) == 0 && + strcmp(creator, object_name(o->get_creator())) == 0) + n++; + } + return(n); +} + +class cl_option * +cl_options::set_value(const char *the_name, cl_base *creator, bool value) +{ + class cl_option *o= get_option(the_name, creator); + + if (o) + o->set_value(value); + return(o); +} + +class cl_option * +cl_options::set_value(const char *the_name, cl_base *creator, char *value) +{ + class cl_option *o= get_option(the_name, creator); + + if (o) + o->set_value(value); + return(o); +} + +class cl_option * +cl_options::set_value(const char *the_name, cl_base *creator, void *value) +{ + class cl_option *o= get_option(the_name, creator); + + if (o) + o->set_value(value); + return(o); +} + +class cl_option * +cl_options::set_value(const char *the_name, cl_base *creator, long value) +{ + class cl_option *o= get_option(the_name, creator); + + if (o) + o->set_value(value); + return(o); +} + +class cl_option * +cl_options::set_value(const char *the_name, cl_base *creator, double value) +{ + class cl_option *o= get_option(the_name, creator); + + if (o) + o->set_value(value); + return(o); +} + + +/* + * Reference to an option + */ + +cl_optref::cl_optref(class cl_base *the_owner) +{ + option =0; + owner= the_owner; +} + +cl_optref::cl_optref(class cl_base *the_owner, class cl_option *new_option) +{ + owner= the_owner; + option= new_option; + application->options->new_option(option); + if (option) + { + option->new_reference(this); + set_name(option->get_name()); + } +} + +cl_optref::~cl_optref(void) +{ + if (option) + { + option->del_reference(this); + if (option->get_creator() == owner) + application->options->del_option(option); + } +} + +class cl_option * +cl_optref::create(class cl_base *creator, + enum option_type type, + const char *the_name, const char *help) +{ + if (option) + option->del_reference(this); + switch (type) + { + case non_opt: + option= 0; + break; + case integer_opt: + option= new cl_number_option(creator, the_name, help); + break; + case float_opt: + option= new cl_float_option(creator, the_name, help); + break; + case bool_opt: + option= new cl_bool_option(creator, the_name, help); + break; + case string_opt: + option= new cl_string_option(creator, the_name, help); + break; + case pointer_opt: + option= new cl_pointer_option(creator, the_name, help); + break; + default: + option= 0; + break; + } + if (option) + { + application->options->new_option(option); + option->new_reference(this); + set_name(option->get_name()); + } + + return(option); +} + +void +cl_optref::default_option(const char *the_name) +{ + class cl_option *o= application->options->get_option(the_name, application); + + if (o && + option) + { + //memcpy(option->get_value(), o->get_value(), sizeof(union option_value)); + *option= *o; + option->inform_users(); + } + /*else + fprintf(stderr,"can not set opt from default, option=%p, o=%p\n",option,o);*/ +} + +class cl_option * +cl_optref::use(void) +{ + if (option) + { + option->del_reference(this); + option->new_reference(this); + } + return(option); +} + +class cl_option * +cl_optref::use(const char *the_name) +{ + if (option) + option->del_reference(this); + option= application->options->get_option(the_name); + if (option) + { + option->new_reference(this); + set_name(option->get_name()); + } + return(option); +} + +void +cl_optref::option_removing(void) +{ + option= 0; +} + +bool +cl_optref::get_value(bool) +{ + if (!option) + { + fprintf(stderr, "Warning: \"%s\" is dereferencing a non-existent " + "bool option: %s\n", object_name(owner), get_name()); + return(false); + } + else + { + bool v; + option->get_value(&v); + return(v); + } +} + +char * +cl_optref::get_value(const char *) +{ + if (!option) + { + char *o= (char *)object_name(owner); + char *n= (char *)get_name(); + fprintf(stderr, "Warning: \"%s\" is dereferencing a non-existent " + "string option: %s\n", o, n?n:"?"); + return(0); + } + else + { + char *s= 0; + option->get_value(&s); + return(s); + } +} + +void * +cl_optref::get_value(void *) +{ + if (!option) + { + fprintf(stderr, "Warning: \"%s\" is dereferencing a non-existent " + "pointer option: %s\n", object_name(owner), get_name()); + return(0); + } + else + { + void *p= 0; + option->get_value(&p); + return(p); + } +} + +long +cl_optref::get_value(long) +{ + if (!option) + { + fprintf(stderr, "Warning: \"%s\" is dereferencing a non-existent " + "number option: %s\n", object_name(owner), get_name()); + return(0); + } + else + { + long l= 0; + option->get_value(&l); + return(l); + } +} + +double +cl_optref::get_value(double) +{ + if (!option) + { + fprintf(stderr, "Warning: \"%s\" is dereferencing a non-existent " + "float option: %s\n", object_name(owner), get_name()); + return(0); + } + else + { + double d= 0; + option->get_value(&d); + return(d); + } +} + + +/* + * BOOL type of option + *____________________________________________________________________________ + * + */ + +cl_bool_option::cl_bool_option(class cl_base *the_creator, + const char *aname, const char *Ihelp): + cl_option(the_creator, aname, Ihelp) +{} + +void +cl_bool_option::print(class cl_console_base *con) +{ + if (/**(bool *)option*/value.bval) + con->dd_printf("TRUE"); + else + con->dd_printf("FALSE"); +} + +void +cl_bool_option::set_value(char *s) +{ + char c; + + if (s) + { + c= toupper(*s); + if (c == '1' || + c == 'T' || + c == 'Y') + /**(bool *)option=*/ value.bval= true; + else + /**(bool *)option=*/ value.bval= false; + } + inform_users(); +} + + +/* + * STRING type of option + *____________________________________________________________________________ + * + */ + +cl_string_option::cl_string_option(class cl_base *the_creator, + const char *aname, const char *Ihelp): + cl_option(the_creator, aname, Ihelp) +{} + +class cl_option & +cl_string_option::operator=(class cl_option &o) +{ + //fprintf(stderr,"string=otheropt%p\"%s\"\nold=%p\"%s\"\n",&o,object_name(&o),value.sval,value.sval); + set_value((o.get_value())->sval); + //fprintf(stderr,"new=%p\"%s\"\n",value.sval,value.sval); + return(*this); +} + +void +cl_string_option::print(class cl_console_base *con) +{ + if (/**(bool *)option*/value.sval) + con->dd_printf("\"%s\"", value.sval); + else + con->dd_printf("(null)"); +} + + +/* + * PONITER type of option + *____________________________________________________________________________ + * + */ + +cl_pointer_option::cl_pointer_option(class cl_base *the_creator, + const char *aname, const char *Ihelp): + cl_option(the_creator, aname, Ihelp) +{} + +class cl_option & +cl_pointer_option::operator=(class cl_option &o) +{ + set_value((o.get_value())->pval); + return(*this); +} + +void +cl_pointer_option::print(class cl_console_base *con) +{ + if (value.pval) + con->dd_printf("\"%p\"", value.pval); + else + con->dd_printf("(null)"); +} + + +/* + * Debug on console + */ +/* +cl_cons_debug_opt::cl_cons_debug_opt(class cl_app *the_app, + char *Iid, + const char *Ihelp): + cl_option(0, Iid, Ihelp) +{ + app= the_app; +} + +void +cl_cons_debug_opt::print(class cl_console_base *con) +{ + if (con->flags & CONS_DEBUG) + con->dd_printf("TRUE"); + else + con->dd_printf("FALSE"); +} + +void +cl_cons_debug_opt::get_value(bool *val) +{ + if (val) + *val= app->get_commander()->actual_console? + (app->get_commander()->actual_console->flags & CONS_DEBUG):0; +} + +void +cl_cons_debug_opt::set_value(bool opt) +{ + if (app->get_commander()->actual_console) + { + if (opt) + app->get_commander()->actual_console->flags|= CONS_DEBUG; + else + app->get_commander()->actual_console->flags&= ~CONS_DEBUG; + } + inform_users(); +} + +void +cl_cons_debug_opt::set_value(char *s) +{ + char c; + + if (s && + app->get_commander()->actual_console) + { + c= toupper(*s); + if (c == '1' || + c == 'T' || + c == 'Y') + set_value(1); + else + set_value(0); + } +} +*/ + +/* + * NUMBER type of option + *____________________________________________________________________________ + * + */ + +cl_number_option::cl_number_option(class cl_base *the_creator, + const char *aname, const char *Ihelp): + cl_option(the_creator, aname, Ihelp) +{} + +void +cl_number_option::print(class cl_console_base *con) +{ + con->dd_printf("%ld", value.ival); +} + +void +cl_number_option::set_value(char *s) +{ + if (s) + value.ival= strtol(s, 0, 0); + inform_users(); +} + + +/* + * FLOAT type of option + *____________________________________________________________________________ + * + */ + +cl_float_option::cl_float_option(class cl_base *the_creator, + const char *aname, const char *Ihelp): + cl_option(the_creator, aname, Ihelp) +{} + +void +cl_float_option::print(class cl_console_base *con) +{ + con->dd_printf("%.3f", value.fval); +} + +void +cl_float_option::set_value(char *s) +{ + if (s) + value.fval= strtod(s, 0); + inform_users(); +} + + +/* End of option.cc */ |
