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/cmd.src/newcmdposix.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/cmd.src/newcmdposix.cc')
| -rw-r--r-- | sim/ucsim/cmd.src/newcmdposix.cc | 696 |
1 files changed, 696 insertions, 0 deletions
diff --git a/sim/ucsim/cmd.src/newcmdposix.cc b/sim/ucsim/cmd.src/newcmdposix.cc new file mode 100644 index 0000000..ce36d89 --- /dev/null +++ b/sim/ucsim/cmd.src/newcmdposix.cc @@ -0,0 +1,696 @@ +/* + * Simulator of microcontrollers (cmd.src/newcmdposix.cc) + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * Copyright (C) 2006, Borut Razem - borut.razem@siol.net + * + * 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 <errno.h> +#include <stdarg.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/time.h> +#include "i_string.h" + +// prj +#include "globals.h" +#include "utils.h" + +// sim +#include "simcl.h" +#include "argcl.h" +#include "appcl.h" + +// local +#include "newcmdposixcl.h" + + +/* + * Command console + *____________________________________________________________________________ + */ + +cl_console::cl_console(const char *_fin, const char *_fout, class cl_app *the_app) +{ + app= the_app; + fin= 0; + if (_fin) + { + fin= mk_io(_fin, cchars("r")); + } + fout= 0; + if (_fout) + { + fout= mk_io(_fout, cchars("w")); + } + prompt= 0; + set_flag(~CONS_NONE, false); + if ((fin && fin->tty) && (fout && fout->tty)) + { + set_interactive(true); + fin->echo(fout); + fin->cooked(); + } + else + ; + frout= 0; + id= 0; + lines_printed= new cl_ustrings(100, 100, "console_cache"); +} + +cl_console::cl_console(cl_f *_fin, cl_f *_fout, class cl_app *the_app) +{ + app= the_app; + fin= _fin; + fout= _fout; + prompt= 0; + set_flag(~CONS_NONE, false); + if ((fin && fin->tty) && (fout && fout->tty)) + { + set_interactive(true); + fin->echo(fout); + fin->cooked(); + } + else + ; + frout= 0; + id= 0; + lines_printed= new cl_ustrings(100, 100, "console_cache"); +} + +class cl_console * +cl_console::clone_for_exec(char *_fin) +{ + class cl_f *fi= 0, *fo= 0; + + if (!_fin) + return(0); + if (fi= mk_io(_fin, "r"), !fi) + { + fprintf(stderr, "Can't open `%s': %s\n", _fin, strerror(errno)); + return(0); + } + + if ((fo= fout->copy("a")) == 0) + { + delete fi; + fprintf(stderr, "Can't re-open output file: %s\n", strerror(errno)); + return(0); + } + + class cl_console *con= new cl_sub_console(this, fi, fo, app); + return(con); +} + +void +cl_console::drop_files(void) // do not close, just ignore +{ + fin= 0; + fout= 0; + frout= 0; + application->get_commander()->update_active(); +} + +void +cl_console::close_files(bool close_in, bool close_out) +{ + if (frout) + delete frout; + if (close_out) + { + if (fout) + { + if (fout->tty) + tu_reset(); + delete fout; + } + fout= 0; + } + if (close_in) + { + if (fin) + delete fin; + fin= 0; + application->get_commander()->update_active(); + } + //drop_files(); +} + +void +cl_console::replace_files(bool close_old, cl_f *new_in, cl_f *new_out) +{ + if (frout) + delete frout; + frout= 0; + if (close_old) + close_files(fin != new_in, fout != new_out); + fin= new_in; + fout= new_out; + application->get_commander()->update_active(); +} + +/* +void +cl_console::set_id(int new_id) +{ + char *s; + + id= new_id; + set_name(s= format_string("console%d fin=%s,%d fout=%s,%d", + id, + fin?fin->get_file_name():"", + fin?fin->file_id:-1, + fout?fout->get_file_name():"", + fout?fout->file_id:-1)); + free(s); +} +*/ + +cl_console::~cl_console(void) +{ + un_redirect(); + if (fout) + { + //if (flags & CONS_PROMPT) + //fout->write_str("\n"); + //fout->flush(); + if (fout->tty) + tu_reset(); + delete fout; + } + if (fin) + { + delete fin; + } +} + + +/* + * Output functions + */ + +void +cl_console::redirect(char *fname, char *mode) +{ + frout= mk_io(fname, mode); + set_flag(CONS_REDIRECTED, true); +} + +void +cl_console::un_redirect(void) +{ + set_flag(CONS_REDIRECTED, false); + if (!frout) + return; + delete frout; + frout= 0; +} + +/* + * Input functions + */ + +bool +cl_console::input_avail(void) +{ + bool ret= false; + if (startup_command.nempty()) + return true; + if (input_active()) + { + ret= fin->input_avail(); + if (ret) + ; + } + return ret; +} + +bool +cl_console::need_check(void) +{ + return fin && (fin->type == F_CONSOLE); +} + +bool +cl_console::set_cooked(bool new_val) +{ + if (!fin) + return false; + if (new_val) + { + if (!fin->get_cooking()) + fin->interactive(fout); + } + else + { + // raw + fin->raw(); + } + return fin->get_cooking(); +} + + +/* Return + -1 if EOF (and buffer is empty) or ^C found + 0 buffer is not ready yet + 1 buffer filled (EOL detected) +*/ + +int +cl_console::read_line(void) +{ + int i= 0; + int b[2]= { 0, 0 }; + + do { + if (startup_command.nempty()) + { + char *s= startup_command; + b[0]= s[0]; + startup_command= &s[1]; + i= 1; + } + else + { + i= fin->read(b, 1); + } + if (i < -1) + { + return -1; + } + if (i == 0) + { + // EOF + if (lbuf.len() == 0) + return -1; + // execute last line, assuming \n + return 1; + } + if (i > 0) + { + // Got a char + if (b[0] == 3) + // ^C, drop and close + return -1; + if ((b[0] == '\n') || + (b[0] == '\r')) + { + if (nl && + (nl != b[0])) + { + nl= 0; + continue; + } + nl= b[0]; + /* + if (lbuf.len() != 0) + { + b[0]= '\n'; + lbuf+= b; + } + */ + return 1; + } + { + char s[2]; + s[0]= b[0]; + s[1]= b[1]; + lbuf+= s; + } + } + } + while (i > 0); + return 0; +} + + +/* + * This console listen on a socket and can accept connection requests + */ +//#ifdef SOCKET_AVAIL + +cl_listen_console::cl_listen_console(int serverport, class cl_app *the_app) +{ + app= the_app; + fin= mk_srv(serverport); + fout= frout= 0; +} + +/* +void +cl_listen_console::set_id(int new_id) +{ + char *s; + + id= new_id; + set_name(s= format_string("listen_console%d port=%d", + id, + fin?fin->server_port:-1)); + free(s); +} +*/ + +int +cl_listen_console::proc_input(class cl_cmdset *cmdset) +{ + //int newsock; + + class cl_commander_base *cmd; + cl_f *in, *out; + + cmd= app->get_commander(); + + srv_accept(fin, &in, &out); + class cl_console_base *c= new cl_console(in, out, app); + c->set_flag(CONS_INTERACTIVE, true); + in->interactive(out); + cmd->add_console(c); + return(0); +} + +//#endif /* SOCKET_AVAIL */ + + +/* + * Sub-console + */ +/* +cl_sub_console::cl_sub_console(class cl_console_base *the_parent, + FILE *fin, FILE *fout, class cl_app *the_app): + cl_console(fin, fout, the_app) +{ + parent= the_parent; +} +*/ +cl_sub_console::cl_sub_console(class cl_console_base *the_parent, + class cl_f *fin, class cl_f *fout, class cl_app *the_app): + cl_console(fin, fout, the_app) +{ + parent= the_parent; +} + +cl_sub_console::~cl_sub_console(void) +{ + class cl_commander_base *c= app->get_commander(); + + if (parent && c) + { + c->activate_console(parent); + } +} + +int +cl_sub_console::init(void) +{ + class cl_commander_base *c= app->get_commander(); + + if (parent && c) + { + c->deactivate_console(parent); + } + cl_console::init(); + set_flag(CONS_ECHO, true); + return(0); +} + +/* +void +cl_sub_console::set_id(int new_id) +{ + char *s; + + id= new_id; + set_name(s= format_string("sub_console%d (of %d) fin=%s,%d fout=%s,%d", + id, + parent?parent->get_id():-1, + fin?fin->get_file_name():"", + fin?fin->file_id:-1, + fout?fout->get_file_name():"", + fout?fout->file_id:-1)); + free(s); +} +*/ + +/* + * Command interpreter + *____________________________________________________________________________ + */ + +int +cl_commander::init(void) +{ + class cl_optref console_on_option(this); + class cl_optref config_file_option(this); + class cl_optref port_number_option(this); + class cl_console_base *con; + int ccnt= 0; + cl_console_base *c; + + console_on_option.init(); + console_on_option.use("console_on"); + config_file_option.init(); + config_file_option.use("config_file"); + port_number_option.init(); + + cl_base::init(); + set_name("Commander"); + active_inputs= new cl_list(10, 5, "active_inputs"); + check_list= new cl_list(10, 5, "check_list"); + + bool need_config= true; + + if (port_number_option.use("port_number")) + { + add_console(c= new cl_listen_console(port_number_option.get_value((long)0), app)); + } + /* + else + { + c= new cl_listen_console(5559, app); + add_console(c); + c->prev_quit= 0; + ccnt= 1; + } + */ + char *Config= config_file_option.get_value(""); + char *cn= console_on_option.get_value(""); + + if (cn) + { + if (strcmp(cn, "-") == 0) + { + class cl_f *in, *out; + in= cp_io(fileno(stdin), cchars("r")); + out= cp_io(fileno(stdout), cchars("w")); + in->interactive(out); + add_console(con= new cl_console(in, out, app)); + config_console= exec_on(con, Config); + if (config_console) + config_console->set_startup(app->startup_command); + else + con->set_startup(app->startup_command); + need_config= false; + if (in->tty) + con->set_flag(CONS_INTERACTIVE, true); + } + else + { + add_console(con= new cl_console(cn, cn, app)); + config_console= exec_on(con, Config); + need_config= false; + } + } + if (cons->get_count() == ccnt) + { + class cl_f *in, *out; + in= cp_io(fileno(stdin), cchars("r")); + out= cp_io(fileno(stdout), cchars("w")); + in->interactive(out); + add_console(con= new cl_console(in, out, app)); + config_console= exec_on(con, Config); + if (config_console) + config_console->set_startup(app->startup_command); + else + con->set_startup(app->startup_command); + need_config= false; + if (in->tty) + con->set_flag(CONS_INTERACTIVE, true); + } + if ( + need_config && + ( + (Config && *Config) + || + app->startup_command.nempty() + ) + ) + { + class cl_f *i= NULL, *o; + if (Config && *Config) + i= mk_io(Config, "r"); + o= cp_io(fileno(stderr), "w"); + con= new cl_console(/*fc*/i, /*stderr*/o, app); + con->set_flag(CONS_NOWELCOME|CONS_ECHO, true); + //exec_on(con, Config); + config_console= con; + con->set_startup(app->startup_command); + add_console(con); + } + return(0); +} + +void +cl_commander::update_active(void) +{ + int i; + + active_inputs->disconn_all(); + check_list->disconn_all(); + + if (config_console) + { + if (!cons->index_of(config_console, NULL)) + config_console= 0; + } + + //printf("List of active cons: "); + for (i= 0; i < cons->count; i++) + { + class cl_console *c= + (class cl_console *)cons->at(i); + class cl_f *f= c->get_fin(); + + if (config_console && + (config_console != c)) + continue; + + if (f && + (f->file_id < 0)) + continue; + + if (c->input_active() && + f) + { + active_inputs->add(f); + //printf("%d,",c->get_id()); + } + if (c->need_check() && + f) + check_list->add(f); + } + //printf("\n"); + //printf("List of check cons: "); + /*for (i= 0; i < check_list->count; i++) + { + class cl_console *c= + (class cl_console *)cons->at(i); + printf("%d,", c->get_id()); + }*/ + //printf("\n"); +} + +int +cl_commander::input_avail(void) +{ + class cl_list *avail= new cl_list(10,5,"avail"); + bool ret= check_inputs(active_inputs, avail); + avail->disconn_all(); + delete avail; + if (!ret) + for (int j = 0; j < cons->count; j++) + { + class cl_console *c = dynamic_cast<class cl_console*>((class cl_console_base*)(cons->at(j))); + chars *s= c->get_startup(); + if (s->nempty()) + { + return true; + } + } + return ret; +} + +int +cl_commander::wait_input(void) +{ + while (!input_avail()) + loop_delay(); + return 0; +} + +int +cl_commander::proc_input(void) +{ + if (config_console) + { + if (!cons->index_of(config_console, NULL)) + config_console= 0; + } + + for (int j = 0; j < cons->count; j++) + { + class cl_console *c = dynamic_cast<class cl_console*>((class cl_console_base*)(cons->at(j))); + class cl_f *f= c->get_fin(); + + if (config_console && + (config_console != c)) + continue; + + if (c->input_active() && + (f || c->has_startup())) + { + if (c->input_avail()) + { + actual_console = c; + int retval = c->proc_input(cmdset); + if (retval) + { + del_console(c); + //delete c; + } + actual_console = 0; + int i= consoles_prevent_quit(); + return(i == 0); + } + } + } + return 0; +} + + +void +cl_commander::check(void) +{ + int i; + + for (i= 0; i < check_list->count; i++) + { + class cl_f *f= (class cl_f *)check_list->at(i); + f->check(); + } +} + +/* End of cmd.src/newcmdposix.cc */ |
