summaryrefslogtreecommitdiff
path: root/sim/ucsim/cmd.src/newcmdposix.cc
diff options
context:
space:
mode:
authorXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
committerXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
commit268a53de823a6750d6256ee1fb1e7707b4b45740 (patch)
tree42c1799a9a82b2f7d9790ee9fe181d72a7274751 /sim/ucsim/cmd.src/newcmdposix.cc
downloadsdcc-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.cc696
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 */