set svn properties
authorborutr <borutr@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 30 Aug 2006 21:17:29 +0000 (21:17 +0000)
committerborutr <borutr@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 30 Aug 2006 21:17:29 +0000 (21:17 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4349 4a8a32a2-be11-0410-ad9d-d568d2c75423

sim/ucsim/cmd.src/newcmdposix.cc
sim/ucsim/cmd.src/newcmdwin32.cc

index f82bcad0629c28c8f05be23938b5cefea44c6da7..0ad9a533520b4d8c86cea3d2eef491932427f6ec 100644 (file)
-/*\r
- * Simulator of microcontrollers (cmd.src/newcmdposix.cc)\r
- *\r
- * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.\r
- * Copyright (C) 2006, Borut Razem - borut.razem@siol.net\r
- *\r
- * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu\r
- *\r
- */\r
-\r
-/* This file is part of microcontroller simulator: ucsim.\r
-\r
-UCSIM is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-UCSIM is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with UCSIM; see the file COPYING.  If not, write to the Free\r
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA\r
-02111-1307, USA. */\r
-/*@1@*/\r
-\r
-#include "ddconfig.h"\r
-\r
-#include <stdio.h>\r
-#include <errno.h>\r
-#include <stdarg.h>\r
-#include <stdlib.h>\r
-#include <sys/types.h>\r
-#include <sys/time.h>\r
-#ifdef SOCKET_AVAIL\r
-# include HEADER_SOCKET\r
-# if defined HAVE_SYS_SOCKET_H\r
-#  include <netinet/in.h>\r
-#  include <arpa/inet.h>\r
-#  include <netdb.h>\r
-# endif\r
-#endif\r
-#if FD_HEADER_OK\r
-# include HEADER_FD\r
-#endif\r
-#ifdef HAVE_UNISTD_H\r
-# include <unistd.h>\r
-#endif\r
-#include "i_string.h"\r
-\r
-#include "cmdlexcl.h"\r
-#include "cmdpars.h"\r
-\r
-// prj\r
-#include "globals.h"\r
-#include "utils.h"\r
-\r
-// sim\r
-#include "simcl.h"\r
-#include "argcl.h"\r
-#include "appcl.h"\r
-\r
-// local\r
-#include "newcmdposixcl.h"\r
-\r
-\r
-/*\r
- * Command console\r
- *____________________________________________________________________________\r
- */\r
-\r
-cl_console::cl_console(char *fin, char *fout, class cl_app *the_app)\r
-{\r
-  FILE *f;\r
-\r
-  app= the_app;\r
-  in= 0;\r
-  if (fin)\r
-    if (f= fopen(fin, "r"), in= f, !f)\r
-      fprintf(stderr, "Can't open `%s': %s\n", fin, strerror(errno));\r
-  out= 0;\r
-  if (fout)\r
-    if (f= fopen(fout, "w"), out= f, !f)\r
-      fprintf(stderr, "Can't open `%s': %s\n", fout, strerror(errno));\r
-  prompt= 0;\r
-  flags= CONS_NONE;\r
-  if (is_tty())\r
-    flags|= CONS_INTERACTIVE;\r
-  else\r
-    ;//fprintf(stderr, "Warning: non-interactive console\n");\r
-  rout= 0;\r
-  id= 0;\r
-  lines_printed= new cl_ustrings(100, 100, "console_cache");\r
-}\r
-\r
-cl_console::cl_console(FILE *fin, FILE *fout, class cl_app *the_app)\r
-{\r
-  app= the_app;\r
-  in = fin;\r
-  out= fout;\r
-  prompt= 0;\r
-  flags= CONS_NONE;\r
-  if (is_tty())\r
-    flags|= CONS_INTERACTIVE;\r
-  else\r
-    ;//fprintf(stderr, "Warning: non-interactive console\n");\r
-  rout= 0;\r
-  id= 0;\r
-  lines_printed= new cl_ustrings(100, 100, "console_cache");\r
-}\r
-\r
-class cl_console *\r
-cl_console::clone_for_exec(char *fin)\r
-{\r
-  FILE *fi= 0, *fo= 0;\r
-\r
-  if (!fin)\r
-    return(0);\r
-  if (fi= fopen(fin, "r"), !fi)\r
-    {\r
-      fprintf(stderr, "Can't open `%s': %s\n", fin, strerror(errno));\r
-      return(0);\r
-    }\r
-  if ((fo= fdopen(dup(fileno(out)), "a")) == 0)\r
-    {\r
-      fclose(fi);\r
-      fprintf(stderr, "Can't re-open output file: %s\n", strerror(errno));\r
-      return(0);\r
-    }\r
-  class cl_console *con= new cl_sub_console(this, fi, fo, app);\r
-  return(con);\r
-}\r
-\r
-cl_console::~cl_console(void)\r
-{\r
-  if (in)\r
-    fclose(in);\r
-  un_redirect();\r
-  if (out)\r
-    {\r
-      if (flags & CONS_PROMPT)\r
-        fprintf(out, "\n");\r
-      fflush(out);\r
-      fclose(out);\r
-    }\r
-  delete prompt_option;\r
-  delete null_prompt_option;\r
-  delete debug_option;\r
-#ifdef SOCKET_AVAIL\r
-  /*  if (sock)\r
-    {\r
-      shutdown(sock, 2);\r
-      close(sock);\r
-      }*/\r
-#endif\r
-}\r
-\r
-\r
-/*\r
- * Output functions\r
- */\r
-\r
-void\r
-cl_console::redirect(char *fname, char *mode)\r
-{\r
-  if ((rout= fopen(fname, mode)) == NULL)\r
-    dd_printf("Unable to open file '%s' for %s: %s\n",\r
-              fname, (mode[0]=='w')?"write":"append", strerror(errno));\r
-}\r
-\r
-void\r
-cl_console::un_redirect(void)\r
-{\r
-  if (!rout)\r
-    return;\r
-  fclose(rout);\r
-  rout = NULL;\r
-}\r
-\r
-int\r
-cl_console::cmd_do_print(char *format, va_list ap)\r
-{\r
-  int ret;\r
-  FILE *f = get_out();\r
-\r
-  if (f)\r
-   {\r
-      ret= vfprintf(f, format, ap);\r
-      fflush(f);\r
-    }\r
-  else\r
-    ret = 0;\r
-\r
-  return ret;\r
-}\r
-\r
-/*\r
- * Input functions\r
- */\r
-\r
-char *\r
-cl_console::read_line(void)\r
-{\r
-  char *s= NULL;\r
-\r
-#ifdef HAVE_GETLINE\r
-  if (getline(&s, 0, in) < 0)\r
-    return(0);\r
-#elif defined HAVE_GETDELIM\r
-  size_t n= 30;\r
-  s= (char *)malloc(n);\r
-  if (getdelim(&s, &n, '\n', in) < 0)\r
-    {\r
-      free(s);\r
-      return(0);\r
-    }\r
-#elif defined HAVE_FGETS\r
-  s= (char *)malloc(300);\r
-  if (fgets(s, 300, in) == NULL)\r
-    {\r
-      free(s);\r
-      return(0);\r
-    }\r
-#endif\r
-  s[strlen(s)-1]= '\0';\r
-  if (s[strlen(s)-1] == '\r')\r
-    s[strlen(s)-1]= '\0';\r
-  flags&= ~CONS_PROMPT;\r
-  return(s);\r
-}\r
-\r
-\r
-/*\r
- * This console listen on a socket and can accept connection requests\r
- */\r
-#ifdef SOCKET_AVAIL\r
-\r
-cl_listen_console::cl_listen_console(int serverport, class cl_app *the_app)\r
-{\r
-  app= the_app;\r
-  if ((sock= make_server_socket(serverport)) >= 0)\r
-    {\r
-      if (listen(sock, 10) < 0)\r
-        fprintf(stderr, "Listen on port %d: %s\n",\r
-                serverport, strerror(errno));\r
-    }\r
-  in= out= rout= 0;\r
-}\r
-\r
-int\r
-cl_listen_console::proc_input(class cl_cmdset *cmdset)\r
-{\r
-  int newsock;\r
-  ACCEPT_SOCKLEN_T size;\r
-  struct sockaddr_in sock_addr;\r
-  class cl_commander_base *cmd;\r
-  FILE *in, *out;\r
-\r
-  cmd= app->get_commander();\r
-  size= sizeof(struct sockaddr);\r
-  newsock= accept(sock, (struct sockaddr*)&sock_addr, &size);\r
-  if (newsock < 0)\r
-    {\r
-      perror("accept");\r
-      return(0);\r
-    }\r
-  if (!(in= fdopen(newsock, "r")))\r
-    fprintf(stderr, "cannot open port for input\n");\r
-  if (!(out= fdopen(newsock, "w")))\r
-    fprintf(stderr, "cannot open port for output\n");\r
-  class cl_console_base *c= new cl_console(in, out, app);\r
-  c->flags|= CONS_INTERACTIVE;\r
-  cmd->add_console(c);\r
-  return(0);\r
-}\r
-\r
-#endif /* SOCKET_AVAIL */\r
-\r
-\r
-/*\r
- * Sub-console\r
- */\r
-\r
-cl_sub_console::cl_sub_console(class cl_console_base *the_parent,\r
-                               FILE *fin, FILE *fout, class cl_app *the_app):\r
-  cl_console(fin, fout, the_app)\r
-{\r
-  parent= the_parent;\r
-}\r
-\r
-cl_sub_console::~cl_sub_console(void)\r
-{\r
-  class cl_commander_base *c= app->get_commander();\r
-\r
-  if (parent && c)\r
-    {\r
-      c->activate_console(parent);\r
-    }\r
-}\r
-\r
-int\r
-cl_sub_console::init(void)\r
-{\r
-  class cl_commander_base *c= app->get_commander();\r
-\r
-  if (parent && c)\r
-    {\r
-      c->deactivate_console(parent);\r
-    }\r
-  cl_console::init();\r
-  flags|= CONS_ECHO;\r
-  return(0);\r
-}\r
-\r
-\r
-/*\r
- * Command interpreter\r
- *____________________________________________________________________________\r
- */\r
-\r
-int\r
-cl_commander::init(void)\r
-{\r
-  class cl_optref console_on_option(this);\r
-  class cl_optref config_file_option(this);\r
-  class cl_optref port_number_option(this);\r
-  class cl_console_base *con;\r
-\r
-  console_on_option.init();\r
-  console_on_option.use("console_on");\r
-  config_file_option.init();\r
-  config_file_option.use("config_file");\r
-  port_number_option.init();\r
-\r
-  cl_base::init();\r
-  set_name("Commander");\r
-\r
-  bool need_config= DD_TRUE;\r
-\r
-#ifdef SOCKET_AVAIL\r
-  if (port_number_option.use("port_number"))\r
-    add_console(new cl_listen_console(port_number_option.get_value((long)0), app));\r
-#endif\r
-\r
-  /* The following code is commented out because it produces gcc warnings\r
-   * newcmd.cc: In member function `virtual int cl_commander::init()':\r
-   * newcmd.cc:785: warning: 'Config' might be used uninitialized in this function\r
-   * newcmd.cc:786: warning: 'cn' might be used uninitialized in this function\r
-   */\r
-  /*\r
-  char *Config= config_file_option.get_value(Config);\r
-  char *cn= console_on_option.get_value(cn);\r
-   */\r
-  /* Here shoud probably be something else, but is still better then the former code... */\r
-  char *Config= config_file_option.get_value("");\r
-  char *cn= console_on_option.get_value("");\r
-\r
-  if (cn)\r
-    {\r
-      add_console(con= new cl_console(cn, cn, app));\r
-      exec_on(con, Config);\r
-      need_config= DD_FALSE;\r
-    }\r
-  if (cons->get_count() == 0)\r
-    {\r
-      add_console(con= new cl_console(stdin, stdout, app));\r
-      exec_on(con, Config);\r
-      need_config= DD_FALSE;\r
-    }\r
-  if (need_config &&\r
-      Config &&\r
-      *Config)\r
-    {\r
-      FILE *fc= fopen(Config, "r");\r
-      if (!fc)\r
-        fprintf(stderr, "Can't open `%s': %s\n", Config, strerror(errno));\r
-      else\r
-        {\r
-          con= new cl_console(fc, stderr, app);\r
-          con->flags|= CONS_NOWELCOME|CONS_ECHO;\r
-          add_console(con);\r
-        }\r
-    }\r
-  return(0);\r
-}\r
-\r
-void\r
-cl_commander::set_fd_set(void)\r
-{\r
-  int i;\r
-\r
-  FD_ZERO(&read_set);\r
-  fd_num = 0;\r
-  for (i = 0; i < cons->count; i++)\r
-    {\r
-      class cl_console *c= dynamic_cast<class cl_console*>((class cl_console_base*)(cons->at(i)));\r
-\r
-      if (c->input_active())\r
-        {\r
-          UCSOCKET_T fd = c->get_in_fd();\r
-          assert(0 <= fd);\r
-\r
-          FD_SET(fd, &read_set);\r
-          if (fd > fd_num)\r
-            fd_num = fd;\r
-        }\r
-    }\r
-  fd_num++;\r
-}\r
-\r
-int\r
-cl_commander::input_avail(void)\r
-{\r
-  struct timeval tv = {0, 0};\r
-  active_set = read_set;\r
-\r
-  int i = select(fd_num, &active_set, NULL, NULL, &tv);\r
-  if (i < 0)\r
-    perror("select");\r
-\r
-  return i;\r
-}\r
-\r
-int\r
-cl_commander::wait_input(void)\r
-{\r
-  prompt();\r
-  active_set = read_set;\r
-  int i = select(fd_num, &active_set, NULL, NULL, NULL);\r
-  return i;\r
-}\r
-\r
-int\r
-cl_commander::proc_input(void)\r
-{\r
-  for (int j = 0; j < cons->count; j++)\r
-    {\r
-      class cl_console *c = dynamic_cast<class cl_console*>((class cl_console_base*)(cons->at(j)));\r
-\r
-      if (c->input_active())\r
-        {\r
-          UCSOCKET_T fd = c->get_in_fd();\r
-          assert(0 <= fd);\r
-\r
-          if (FD_ISSET(fd, &active_set))\r
-            {\r
-              actual_console = c;\r
-              int retval = c->proc_input(cmdset);\r
-              if (retval)\r
-                {\r
-                  del_console(c);\r
-                  delete c;\r
-                }\r
-              actual_console = 0;\r
-              return(0 == cons->count);\r
-            }\r
-        }\r
-    }\r
-  return 0;\r
-}\r
-\r
-\r
-/* End of cmd.src/newcmdposix.cc */\r
+/*
+ * 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>
+#ifdef SOCKET_AVAIL
+# include HEADER_SOCKET
+# if defined HAVE_SYS_SOCKET_H
+#  include <netinet/in.h>
+#  include <arpa/inet.h>
+#  include <netdb.h>
+# endif
+#endif
+#if FD_HEADER_OK
+# include HEADER_FD
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include "i_string.h"
+
+#include "cmdlexcl.h"
+#include "cmdpars.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(char *fin, char *fout, class cl_app *the_app)
+{
+  FILE *f;
+
+  app= the_app;
+  in= 0;
+  if (fin)
+    if (f= fopen(fin, "r"), in= f, !f)
+      fprintf(stderr, "Can't open `%s': %s\n", fin, strerror(errno));
+  out= 0;
+  if (fout)
+    if (f= fopen(fout, "w"), out= f, !f)
+      fprintf(stderr, "Can't open `%s': %s\n", fout, strerror(errno));
+  prompt= 0;
+  flags= CONS_NONE;
+  if (is_tty())
+    flags|= CONS_INTERACTIVE;
+  else
+    ;//fprintf(stderr, "Warning: non-interactive console\n");
+  rout= 0;
+  id= 0;
+  lines_printed= new cl_ustrings(100, 100, "console_cache");
+}
+
+cl_console::cl_console(FILE *fin, FILE *fout, class cl_app *the_app)
+{
+  app= the_app;
+  in = fin;
+  out= fout;
+  prompt= 0;
+  flags= CONS_NONE;
+  if (is_tty())
+    flags|= CONS_INTERACTIVE;
+  else
+    ;//fprintf(stderr, "Warning: non-interactive console\n");
+  rout= 0;
+  id= 0;
+  lines_printed= new cl_ustrings(100, 100, "console_cache");
+}
+
+class cl_console *
+cl_console::clone_for_exec(char *fin)
+{
+  FILE *fi= 0, *fo= 0;
+
+  if (!fin)
+    return(0);
+  if (fi= fopen(fin, "r"), !fi)
+    {
+      fprintf(stderr, "Can't open `%s': %s\n", fin, strerror(errno));
+      return(0);
+    }
+  if ((fo= fdopen(dup(fileno(out)), "a")) == 0)
+    {
+      fclose(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);
+}
+
+cl_console::~cl_console(void)
+{
+  if (in)
+    fclose(in);
+  un_redirect();
+  if (out)
+    {
+      if (flags & CONS_PROMPT)
+        fprintf(out, "\n");
+      fflush(out);
+      fclose(out);
+    }
+  delete prompt_option;
+  delete null_prompt_option;
+  delete debug_option;
+#ifdef SOCKET_AVAIL
+  /*  if (sock)
+    {
+      shutdown(sock, 2);
+      close(sock);
+      }*/
+#endif
+}
+
+
+/*
+ * Output functions
+ */
+
+void
+cl_console::redirect(char *fname, char *mode)
+{
+  if ((rout= fopen(fname, mode)) == NULL)
+    dd_printf("Unable to open file '%s' for %s: %s\n",
+              fname, (mode[0]=='w')?"write":"append", strerror(errno));
+}
+
+void
+cl_console::un_redirect(void)
+{
+  if (!rout)
+    return;
+  fclose(rout);
+  rout = NULL;
+}
+
+int
+cl_console::cmd_do_print(char *format, va_list ap)
+{
+  int ret;
+  FILE *f = get_out();
+
+  if (f)
+   {
+      ret= vfprintf(f, format, ap);
+      fflush(f);
+    }
+  else
+    ret = 0;
+
+  return ret;
+}
+
+/*
+ * Input functions
+ */
+
+char *
+cl_console::read_line(void)
+{
+  char *s= NULL;
+
+#ifdef HAVE_GETLINE
+  if (getline(&s, 0, in) < 0)
+    return(0);
+#elif defined HAVE_GETDELIM
+  size_t n= 30;
+  s= (char *)malloc(n);
+  if (getdelim(&s, &n, '\n', in) < 0)
+    {
+      free(s);
+      return(0);
+    }
+#elif defined HAVE_FGETS
+  s= (char *)malloc(300);
+  if (fgets(s, 300, in) == NULL)
+    {
+      free(s);
+      return(0);
+    }
+#endif
+  s[strlen(s)-1]= '\0';
+  if (s[strlen(s)-1] == '\r')
+    s[strlen(s)-1]= '\0';
+  flags&= ~CONS_PROMPT;
+  return(s);
+}
+
+
+/*
+ * 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;
+  if ((sock= make_server_socket(serverport)) >= 0)
+    {
+      if (listen(sock, 10) < 0)
+        fprintf(stderr, "Listen on port %d: %s\n",
+                serverport, strerror(errno));
+    }
+  in= out= rout= 0;
+}
+
+int
+cl_listen_console::proc_input(class cl_cmdset *cmdset)
+{
+  int newsock;
+  ACCEPT_SOCKLEN_T size;
+  struct sockaddr_in sock_addr;
+  class cl_commander_base *cmd;
+  FILE *in, *out;
+
+  cmd= app->get_commander();
+  size= sizeof(struct sockaddr);
+  newsock= accept(sock, (struct sockaddr*)&sock_addr, &size);
+  if (newsock < 0)
+    {
+      perror("accept");
+      return(0);
+    }
+  if (!(in= fdopen(newsock, "r")))
+    fprintf(stderr, "cannot open port for input\n");
+  if (!(out= fdopen(newsock, "w")))
+    fprintf(stderr, "cannot open port for output\n");
+  class cl_console_base *c= new cl_console(in, out, app);
+  c->flags|= CONS_INTERACTIVE;
+  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(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();
+  flags|= CONS_ECHO;
+  return(0);
+}
+
+
+/*
+ * 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;
+
+  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");
+
+  bool need_config= DD_TRUE;
+
+#ifdef SOCKET_AVAIL
+  if (port_number_option.use("port_number"))
+    add_console(new cl_listen_console(port_number_option.get_value((long)0), app));
+#endif
+
+  /* The following code is commented out because it produces gcc warnings
+   * newcmd.cc: In member function `virtual int cl_commander::init()':
+   * newcmd.cc:785: warning: 'Config' might be used uninitialized in this function
+   * newcmd.cc:786: warning: 'cn' might be used uninitialized in this function
+   */
+  /*
+  char *Config= config_file_option.get_value(Config);
+  char *cn= console_on_option.get_value(cn);
+   */
+  /* Here shoud probably be something else, but is still better then the former code... */
+  char *Config= config_file_option.get_value("");
+  char *cn= console_on_option.get_value("");
+
+  if (cn)
+    {
+      add_console(con= new cl_console(cn, cn, app));
+      exec_on(con, Config);
+      need_config= DD_FALSE;
+    }
+  if (cons->get_count() == 0)
+    {
+      add_console(con= new cl_console(stdin, stdout, app));
+      exec_on(con, Config);
+      need_config= DD_FALSE;
+    }
+  if (need_config &&
+      Config &&
+      *Config)
+    {
+      FILE *fc= fopen(Config, "r");
+      if (!fc)
+        fprintf(stderr, "Can't open `%s': %s\n", Config, strerror(errno));
+      else
+        {
+          con= new cl_console(fc, stderr, app);
+          con->flags|= CONS_NOWELCOME|CONS_ECHO;
+          add_console(con);
+        }
+    }
+  return(0);
+}
+
+void
+cl_commander::set_fd_set(void)
+{
+  int i;
+
+  FD_ZERO(&read_set);
+  fd_num = 0;
+  for (i = 0; i < cons->count; i++)
+    {
+      class cl_console *c= dynamic_cast<class cl_console*>((class cl_console_base*)(cons->at(i)));
+
+      if (c->input_active())
+        {
+          UCSOCKET_T fd = c->get_in_fd();
+          assert(0 <= fd);
+
+          FD_SET(fd, &read_set);
+          if (fd > fd_num)
+            fd_num = fd;
+        }
+    }
+  fd_num++;
+}
+
+int
+cl_commander::input_avail(void)
+{
+  struct timeval tv = {0, 0};
+  active_set = read_set;
+
+  int i = select(fd_num, &active_set, NULL, NULL, &tv);
+  if (i < 0)
+    perror("select");
+
+  return i;
+}
+
+int
+cl_commander::wait_input(void)
+{
+  prompt();
+  active_set = read_set;
+  int i = select(fd_num, &active_set, NULL, NULL, NULL);
+  return i;
+}
+
+int
+cl_commander::proc_input(void)
+{
+  for (int j = 0; j < cons->count; j++)
+    {
+      class cl_console *c = dynamic_cast<class cl_console*>((class cl_console_base*)(cons->at(j)));
+
+      if (c->input_active())
+        {
+          UCSOCKET_T fd = c->get_in_fd();
+          assert(0 <= fd);
+
+          if (FD_ISSET(fd, &active_set))
+            {
+              actual_console = c;
+              int retval = c->proc_input(cmdset);
+              if (retval)
+                {
+                  del_console(c);
+                  delete c;
+                }
+              actual_console = 0;
+              return(0 == cons->count);
+            }
+        }
+    }
+  return 0;
+}
+
+
+/* End of cmd.src/newcmdposix.cc */
index d49b6d175d352651bad7443a28c981262c9fa5a8..460b04d0dda870264f6ad86ddd832619b10dd217 100644 (file)
-/*\r
- * Simulator of microcontrollers (cmd.src/newcmdwin32.cc)\r
- *\r
- * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.\r
- * Copyright (C) 2006, Borut Razem - borut.razem@siol.net\r
- *\r
- * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu\r
- *\r
- */\r
-\r
-/* This file is part of microcontroller simulator: ucsim.\r
-\r
-UCSIM is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-UCSIM is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with UCSIM; see the file COPYING.  If not, write to the Free\r
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA\r
-02111-1307, USA. */\r
-/*@1@*/\r
-\r
-#include "ddconfig.h"\r
-\r
-#include <stdio.h>\r
-#include <errno.h>\r
-#include <stdarg.h>\r
-#include <stdlib.h>\r
-#include <sys/types.h>\r
-#include <sys/time.h>\r
-#include <assert.h>\r
-#include <fcntl.h>\r
-#include <windows.h>\r
-\r
-#include "i_string.h"\r
-\r
-#include "cmdlexcl.h"\r
-#include "cmdpars.h"\r
-\r
-// prj\r
-#include "globals.h"\r
-#include "utils.h"\r
-\r
-// sim\r
-#include "simcl.h"\r
-#include "argcl.h"\r
-#include "appcl.h"\r
-\r
-// local\r
-#include "newcmdwin32cl.h"\r
-\r
-\r
-/*\r
- * Channel\r
- *____________________________________________________________________________\r
- */\r
-\r
-inline void\r
-cl_channel::set(void)\r
-{\r
-  fp = 0;\r
-  handle = INVALID_HANDLE_VALUE;\r
-  type = CH_UNDEF;\r
-}\r
-\r
-inline void\r
-cl_channel::set(HANDLE _handle, e_handle_type _type)\r
-{\r
-  assert(INVALID_HANDLE_VALUE != _handle);\r
-\r
-  fp = 0;\r
-  handle = _handle;\r
-  type = (_type == CH_UNDEF) ? guess_type() : _type;\r
-}\r
-\r
-inline void\r
-cl_channel::set(FILE *_fp, e_handle_type _type)\r
-{\r
-  assert(_fp);\r
-  fp = _fp;\r
-  handle = (HANDLE)_get_osfhandle(fileno(fp));\r
-  assert(INVALID_HANDLE_VALUE != handle);\r
-  type = (_type == CH_UNDEF) ? guess_type() : _type;\r
-}\r
-\r
-void\r
-cl_channel::close(void)\r
-{\r
-  assert(INVALID_HANDLE_VALUE != handle);\r
-\r
-  if (CH_SOCKET == type)\r
-    {\r
-      shutdown((SOCKET)handle, SD_BOTH);\r
-      closesocket((SOCKET)handle);\r
-    }\r
-  if (fp)\r
-    fclose(fp);\r
-  else if (CH_SOCKET != type)\r
-    CloseHandle(handle);\r
-\r
-  fp = 0;\r
-  handle = INVALID_HANDLE_VALUE;\r
-  type = CH_UNDEF;\r
-}\r
-\r
-/*\r
- * Command console\r
- *____________________________________________________________________________\r
- */\r
-\r
-cl_console::cl_console(char *fin, char *fout, class cl_app *the_app)\r
-{\r
-  FILE *f;\r
-\r
-  app = the_app;\r
-  if (fin)\r
-    {\r
-      if (!(f = fopen(fin, "r")))\r
-        fprintf(stderr, "Can't open `%s': %s\n", fin, strerror(errno));\r
-      in.set(f, CH_FILE);\r
-    }\r
-\r
-  if (fout)\r
-    {\r
-      if (!(f = fopen(fout, "w")))\r
-        fprintf(stderr, "Can't open `%s': %s\n", fout, strerror(errno));\r
-      out.set(f, CH_FILE);\r
-    }\r
-\r
-  prompt = 0;\r
-  flags = CONS_NONE;\r
-  if (in.is_tty())\r
-    flags |= CONS_INTERACTIVE;\r
-  else\r
-    ;//fprintf(stderr, "Warning: non-interactive console\n");\r
-  id = 0;\r
-  lines_printed = new cl_ustrings(100, 100, "console_cache");\r
-}\r
-\r
-cl_console::cl_console(FILE *fin, FILE *fout, class cl_app *the_app)\r
-{\r
-  app = the_app;\r
-  in.set(fin);\r
-  out.set(fout);\r
-\r
-  prompt = 0;\r
-  flags = CONS_NONE;\r
-  if (in.is_tty())\r
-    flags |= CONS_INTERACTIVE;\r
-  else\r
-    ;//fprintf(stderr, "Warning: non-interactive console\n");\r
-  id = 0;\r
-  lines_printed = new cl_ustrings(100, 100, "console_cache");\r
-}\r
-\r
-cl_console::cl_console(cl_channel _in, cl_channel _out, class cl_app *the_app)\r
-{\r
-  app = the_app;\r
-  in = _in;\r
-  out = _out;\r
-\r
-  prompt = 0;\r
-  flags = CONS_NONE;\r
-  if (in.is_tty())\r
-    flags |= CONS_INTERACTIVE;\r
-  else\r
-    ;//fprintf(stderr, "Warning: non-interactive console\n");\r
-  id = 0;\r
-  lines_printed= new cl_ustrings(100, 100, "console_cache");\r
-}\r
-\r
-class cl_console *\r
-cl_console::clone_for_exec(char *fin)\r
-{\r
-  FILE *fi;\r
-  if (!fin)\r
-    return 0;\r
-\r
-  if (!(fi = fopen(fin, "r")))\r
-    {\r
-      fprintf(stderr, "Can't open `%s': %s\n", fin, strerror(errno));\r
-      return 0;\r
-    }\r
-  cl_channel ch_in = cl_channel(fi, CH_FILE);\r
-  class cl_console *con= new cl_sub_console(this, ch_in, out, app);\r
-  return con;\r
-}\r
-\r
-cl_console::~cl_console(void)\r
-{\r
-  if (CH_UNDEF != in.get_type())\r
-    in.close();\r
-  un_redirect();\r
-  if (CH_UNDEF != out.get_type())\r
-    {\r
-      if (flags & CONS_PROMPT)\r
-        dd_printf("\n");\r
-      out.close();\r
-    }\r
-  delete prompt_option;\r
-  delete null_prompt_option;\r
-  delete debug_option;\r
-}\r
-\r
-\r
-/*\r
- * Output functions\r
- */\r
-\r
-void\r
-cl_console::redirect(char *fname, char *mode)\r
-{\r
-  FILE *fp = fopen(fname, mode);\r
-  if (!fp)\r
-    dd_printf("Unable to open file '%s' for %s: %s\n",\r
-      fname, (mode[0]=='w') ? "write" : "append", strerror(errno));\r
-  out.set(fp, CH_FILE);\r
-}\r
-\r
-void\r
-cl_console::un_redirect(void)\r
-{\r
-  if (CH_UNDEF != rout.get_type())\r
-    out.close();\r
-}\r
-\r
-int\r
-cl_console::cmd_do_print(char *format, va_list ap)\r
-{\r
-  FILE *f = get_out()->get_fp();\r
-\r
-  if (f)\r
-   {\r
-      int ret = vfprintf(f, format, ap);\r
-      fflush(f);\r
-      return ret;\r
-    }\r
-  else\r
-    return 0;\r
-}\r
-\r
-/*\r
- * Input functions\r
- */\r
-\r
-char *\r
-cl_console::read_line(void)\r
-{\r
-#define BUF_LEN 1024\r
-\r
-  TRACE("%d-%s\n", get_id(), __PRETTY_FUNCTION__);\r
-\r
-  char *s = NULL;\r
-  FILE *fp = in.get_fp();\r
-  assert(fp);\r
-\r
-#ifdef HAVE_GETLINE\r
-  if (getline(&s, 0, fp) < 0)\r
-    return(0);\r
-#elif defined HAVE_GETDELIM\r
-  size_t n = BUF_LEN;\r
-  s = (char *)malloc(n);\r
-  if (getdelim(&s, &n, '\n', fp) < 0)\r
-    {\r
-      free(s);\r
-      return(0);\r
-    }\r
-#elif defined HAVE_FGETS\r
-  s = (char *)malloc(BUF_LEN);\r
-  if (fgets(s, BUF_LEN, fp) == NULL)\r
-    {\r
-      free(s);\r
-      return(0);\r
-    }\r
-#endif\r
-  s[strlen(s)-1]= '\0';\r
-  if (s[strlen(s)-1] == '\r')\r
-    s[strlen(s)-1]= '\0';\r
-  flags&= ~CONS_PROMPT;\r
-  return(s);\r
-}\r
-\r
-\r
-/*\r
- * This console cl_listen_console on a socket and can accept connection requests\r
- */\r
-\r
-cl_listen_console::cl_listen_console(int serverport, class cl_app *the_app)\r
-{\r
-  SOCKET sock;\r
-  app = the_app;\r
-\r
-  if (INVALID_SOCKET != (sock = make_server_socket(serverport)))\r
-    {\r
-      if (SOCKET_ERROR == listen(sock, 10))\r
-        fprintf(stderr, "Can't listen on port %d: %d\n", serverport, WSAGetLastError());\r
-    }\r
-  in.set((HANDLE)sock, CH_SOCKET);\r
-}\r
-\r
-int\r
-cl_listen_console::proc_input(class cl_cmdset *cmdset)\r
-{\r
-  class cl_commander_base *cmd = app->get_commander();\r
-\r
-  struct sockaddr_in sock_addr;\r
-  ACCEPT_SOCKLEN_T size = sizeof(struct sockaddr);\r
-  SOCKET newsock = accept((SOCKET)get_in_fd(), (struct sockaddr*)&sock_addr, &size);\r
-\r
-  if (INVALID_SOCKET == newsock)\r
-    {\r
-      fprintf(stderr, "Can't accept: %d\n", WSAGetLastError());\r
-      return(0);\r
-    }\r
-\r
-  int fh = _open_osfhandle((intptr_t)newsock, _O_TEXT);\r
-  if (-1 == fh)\r
-    {\r
-      fprintf(stderr, "Can't _open_osfhandle\n");\r
-    }\r
-  FILE *fp = fdopen(fh, "r");\r
-  if (!fp)\r
-    fprintf(stderr, "Can't open port for input\n");\r
-  cl_channel ch_in = cl_channel(fp, CH_SOCKET);\r
-\r
-  fh = _open_osfhandle((intptr_t)newsock, _O_TEXT);\r
-  if (-1 == fh)\r
-    {\r
-      fprintf(stderr, "Can't _open_osfhandle\n");\r
-    }\r
-  fp = fdopen(fh, "w");\r
-  if (!fp)\r
-    fprintf(stderr, "Can't open port for output\n");\r
-  cl_channel ch_out = cl_channel(fp, CH_SOCKET);\r
-\r
-  class cl_console_base *c = new cl_console(ch_in, ch_out, app);\r
-  c->flags |= CONS_INTERACTIVE;\r
-  cmd->add_console(c);\r
-\r
-  return 0;\r
-}\r
-\r
-\r
-/*\r
- * Sub-console\r
- */\r
-\r
-cl_sub_console::cl_sub_console(class cl_console_base *the_parent,\r
-  cl_channel _in, cl_channel _out, class cl_app *the_app):\r
-  cl_console(_in, _out, the_app)\r
-{\r
-  parent = the_parent;\r
-}\r
-\r
-cl_sub_console::~cl_sub_console(void)\r
-{\r
-  class cl_commander_base *c = app->get_commander();\r
-\r
-  if (parent && c)\r
-    {\r
-      c->activate_console(parent);\r
-    }\r
-}\r
-\r
-int\r
-cl_sub_console::init(void)\r
-{\r
-  class cl_commander_base *c = app->get_commander();\r
-\r
-  if (parent && c)\r
-    {\r
-      c->deactivate_console(parent);\r
-    }\r
-  cl_console::init();\r
-  flags |= CONS_ECHO;\r
-  return 0;\r
-}\r
-\r
-\r
-/*\r
- * Command interpreter\r
- *____________________________________________________________________________\r
- */\r
-\r
-int\r
-cl_commander::init(void)\r
-{\r
-  TRACE("%s\n", __PRETTY_FUNCTION__);\r
-\r
-  class cl_optref console_on_option(this);\r
-  class cl_optref config_file_option(this);\r
-  class cl_optref port_number_option(this);\r
-  class cl_console_base *con;\r
-\r
-  console_on_option.init();\r
-  console_on_option.use("console_on");\r
-  config_file_option.init();\r
-  config_file_option.use("config_file");\r
-  port_number_option.init();\r
-\r
-  cl_base::init();\r
-  set_name("Commander");\r
-\r
-  bool need_config = DD_TRUE;\r
-\r
-  if (port_number_option.use("port_number"))\r
-    add_console(new cl_listen_console(port_number_option.get_value((long)0), app));\r
-\r
-  /* The following code is commented out because it produces gcc warnings\r
-   * newcmd.cc: In member function `virtual int cl_commander::init()':\r
-   * newcmd.cc:785: warning: 'Config' might be used uninitialized in this function\r
-   * newcmd.cc:786: warning: 'cn' might be used uninitialized in this function\r
-   */\r
-  /*\r
-  char *Config= config_file_option.get_value(Config);\r
-  char *cn= console_on_option.get_value(cn);\r
-   */\r
-  /* Here shoud probably be something else, but is still better then the former code... */\r
-  char *Config = config_file_option.get_value("");\r
-  char *cn = console_on_option.get_value("");\r
-\r
-  if (cn)\r
-    {\r
-      add_console(con = new cl_console(cn, cn, app));\r
-      exec_on(con, Config);\r
-      need_config = DD_FALSE;\r
-    }\r
-  if (cons->get_count() == 0)\r
-    {\r
-      add_console(con = new cl_console(stdin, stdout, app));\r
-      exec_on(con, Config);\r
-      need_config = DD_FALSE;\r
-    }\r
-  if (need_config && Config && *Config)\r
-    {\r
-      FILE *fc = fopen(Config, "r");\r
-      if (!fc)\r
-        fprintf(stderr, "Can't open `%s': %s\n", Config, strerror(errno));\r
-      else\r
-        {\r
-          con = new cl_console(fc, stderr, app);\r
-          con->flags |= CONS_NOWELCOME | CONS_ECHO;\r
-          add_console(con);\r
-        }\r
-    }\r
-  return(0);\r
-}\r
-\r
-void\r
-cl_commander::set_fd_set(void)\r
-{\r
-  TRACE("%s\n", __PRETTY_FUNCTION__);\r
-\r
-  int i;\r
-\r
-  FD_ZERO(&read_set);\r
-\r
-  for (i = 0; i < cons->count; i++)\r
-    {\r
-      class cl_console *c= dynamic_cast<class cl_console*>((class cl_console_base*)(cons->at(i)));\r
-\r
-      if (c->input_active() && CH_SOCKET == c->in.get_type())\r
-        {\r
-          HANDLE fd = c->get_in_fd();\r
-          assert(INVALID_HANDLE_VALUE != fd);\r
-\r
-          FD_SET((SOCKET)fd, &read_set);\r
-        }\r
-    }\r
-}\r
-\r
-int\r
-cl_commander::console_count(void)\r
-{\r
-  int i = 0;\r
-\r
-  for (int j = 0; j < cons->count; j++)\r
-    {\r
-      class cl_console *c = dynamic_cast<class cl_console*>((class cl_console_base*)(cons->at(j)));\r
-\r
-      if (c->input_active())\r
-        {\r
-          switch (c->in.get_type())\r
-            {\r
-            case CH_CONSOLE:\r
-            case CH_FILE:\r
-            case CH_SERIAL:\r
-              ++i;\r
-              break;\r
-\r
-            default:\r
-              break;\r
-            }\r
-        }\r
-    }\r
-\r
-  return i;\r
-}\r
-\r
-int\r
-cl_commander::console_input_avail(void)\r
-{\r
-  int i = 0;\r
-\r
-  FD_ZERO(&console_active_set);\r
-  for (int j = 0; j < cons->count; j++)\r
-    {\r
-      class cl_console *c = dynamic_cast<class cl_console*>((class cl_console_base*)(cons->at(j)));\r
-\r
-      if (c->input_avail())\r
-        {\r
-          HANDLE fd = c->get_in_fd();\r
-          assert(INVALID_HANDLE_VALUE != fd);\r
-\r
-          switch (c->in.get_type())\r
-            {\r
-            case CH_CONSOLE:\r
-            case CH_FILE:\r
-            case CH_SERIAL:\r
-              FD_SET((SOCKET)fd, &console_active_set);\r
-              ++i;\r
-              break;\r
-\r
-            default:\r
-              break;\r
-            }\r
-        }\r
-    }\r
-\r
-  return i;\r
-}\r
-\r
-int\r
-cl_commander::socket_input_avail(long timeout, bool sleep)\r
-{\r
-  active_set = read_set;\r
-\r
-  if (active_set.fd_count)\r
-    {\r
-      struct timeval tv = {0, 0};\r
-\r
-      struct timeval *tvp = sleep ? NULL : &tv;\r
-\r
-      int i = select(0, &active_set, NULL, NULL, tvp);\r
-      if (SOCKET_ERROR == i)\r
-        {\r
-          fprintf(stderr, "Can't select: %d\n", WSAGetLastError());\r
-          return 0;\r
-        }\r
-\r
-      return i;\r
-    }\r
-  else\r
-    {\r
-      Sleep(timeout / 1000);\r
-      return 0;\r
-    }\r
-}\r
-\r
-int\r
-cl_commander::input_avail_timeout(long timeout)\r
-{\r
-  TRACE("%s\n", __PRETTY_FUNCTION__);\r
-\r
-  int n;\r
-  if (0 != (n = console_input_avail()))\r
-    FD_ZERO(&active_set);\r
-  else\r
-       n = socket_input_avail(timeout, false);\r
-\r
-  return n;\r
-}\r
-\r
-#define CONSOLE_TIMEOUT 300000\r
-\r
-int\r
-cl_commander::wait_input(void)\r
-{\r
-  TRACE("%s\n", __PRETTY_FUNCTION__);\r
-\r
-  prompt();\r
-\r
-  if (0 < console_count())\r
-    {\r
-      int n;\r
-\r
-      while (0 == (n = input_avail_timeout(CONSOLE_TIMEOUT)))\r
-        ;\r
-\r
-      return n;\r
-    }\r
-  else\r
-    {\r
-      FD_ZERO(&console_active_set);\r
-      return socket_input_avail(0, true);\r
-    }\r
-}\r
-\r
-int\r
-cl_commander::proc_input(void)\r
-{\r
-  TRACE("%s\n", __PRETTY_FUNCTION__);\r
-\r
-  for (int j = 0; j < cons->count; j++)\r
-    {\r
-      class cl_console *c = dynamic_cast<class cl_console*>((class cl_console_base*)(cons->at(j)));\r
-\r
-      if (c->input_active())\r
-        {\r
-          HANDLE fd = c->get_in_fd();\r
-          assert(INVALID_HANDLE_VALUE != fd);\r
-\r
-          if (FD_ISSET(fd, &active_set) || FD_ISSET(fd, &console_active_set))\r
-            {\r
-              actual_console = c;\r
-              if (c->proc_input(cmdset))\r
-                {\r
-                  del_console(c);\r
-                  delete c;\r
-                }\r
-              actual_console = 0;\r
-              return 0 == cons->count;\r
-            }\r
-        }\r
-    }\r
-  return 0;\r
-}\r
-\r
-\r
-/* End of cmd.src/newcmdwin32.cc */\r
+/*
+ * Simulator of microcontrollers (cmd.src/newcmdwin32.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 <assert.h>
+#include <fcntl.h>
+#include <windows.h>
+
+#include "i_string.h"
+
+#include "cmdlexcl.h"
+#include "cmdpars.h"
+
+// prj
+#include "globals.h"
+#include "utils.h"
+
+// sim
+#include "simcl.h"
+#include "argcl.h"
+#include "appcl.h"
+
+// local
+#include "newcmdwin32cl.h"
+
+
+/*
+ * Channel
+ *____________________________________________________________________________
+ */
+
+inline void
+cl_channel::set(void)
+{
+  fp = 0;
+  handle = INVALID_HANDLE_VALUE;
+  type = CH_UNDEF;
+}
+
+inline void
+cl_channel::set(HANDLE _handle, e_handle_type _type)
+{
+  assert(INVALID_HANDLE_VALUE != _handle);
+
+  fp = 0;
+  handle = _handle;
+  type = (_type == CH_UNDEF) ? guess_type() : _type;
+}
+
+inline void
+cl_channel::set(FILE *_fp, e_handle_type _type)
+{
+  assert(_fp);
+  fp = _fp;
+  handle = (HANDLE)_get_osfhandle(fileno(fp));
+  assert(INVALID_HANDLE_VALUE != handle);
+  type = (_type == CH_UNDEF) ? guess_type() : _type;
+}
+
+void
+cl_channel::close(void)
+{
+  assert(INVALID_HANDLE_VALUE != handle);
+
+  if (CH_SOCKET == type)
+    {
+      shutdown((SOCKET)handle, SD_BOTH);
+      closesocket((SOCKET)handle);
+    }
+  if (fp)
+    fclose(fp);
+  else if (CH_SOCKET != type)
+    CloseHandle(handle);
+
+  fp = 0;
+  handle = INVALID_HANDLE_VALUE;
+  type = CH_UNDEF;
+}
+
+/*
+ * Command console
+ *____________________________________________________________________________
+ */
+
+cl_console::cl_console(char *fin, char *fout, class cl_app *the_app)
+{
+  FILE *f;
+
+  app = the_app;
+  if (fin)
+    {
+      if (!(f = fopen(fin, "r")))
+        fprintf(stderr, "Can't open `%s': %s\n", fin, strerror(errno));
+      in.set(f, CH_FILE);
+    }
+
+  if (fout)
+    {
+      if (!(f = fopen(fout, "w")))
+        fprintf(stderr, "Can't open `%s': %s\n", fout, strerror(errno));
+      out.set(f, CH_FILE);
+    }
+
+  prompt = 0;
+  flags = CONS_NONE;
+  if (in.is_tty())
+    flags |= CONS_INTERACTIVE;
+  else
+    ;//fprintf(stderr, "Warning: non-interactive console\n");
+  id = 0;
+  lines_printed = new cl_ustrings(100, 100, "console_cache");
+}
+
+cl_console::cl_console(FILE *fin, FILE *fout, class cl_app *the_app)
+{
+  app = the_app;
+  in.set(fin);
+  out.set(fout);
+
+  prompt = 0;
+  flags = CONS_NONE;
+  if (in.is_tty())
+    flags |= CONS_INTERACTIVE;
+  else
+    ;//fprintf(stderr, "Warning: non-interactive console\n");
+  id = 0;
+  lines_printed = new cl_ustrings(100, 100, "console_cache");
+}
+
+cl_console::cl_console(cl_channel _in, cl_channel _out, class cl_app *the_app)
+{
+  app = the_app;
+  in = _in;
+  out = _out;
+
+  prompt = 0;
+  flags = CONS_NONE;
+  if (in.is_tty())
+    flags |= CONS_INTERACTIVE;
+  else
+    ;//fprintf(stderr, "Warning: non-interactive console\n");
+  id = 0;
+  lines_printed= new cl_ustrings(100, 100, "console_cache");
+}
+
+class cl_console *
+cl_console::clone_for_exec(char *fin)
+{
+  FILE *fi;
+  if (!fin)
+    return 0;
+
+  if (!(fi = fopen(fin, "r")))
+    {
+      fprintf(stderr, "Can't open `%s': %s\n", fin, strerror(errno));
+      return 0;
+    }
+  cl_channel ch_in = cl_channel(fi, CH_FILE);
+  class cl_console *con= new cl_sub_console(this, ch_in, out, app);
+  return con;
+}
+
+cl_console::~cl_console(void)
+{
+  if (CH_UNDEF != in.get_type())
+    in.close();
+  un_redirect();
+  if (CH_UNDEF != out.get_type())
+    {
+      if (flags & CONS_PROMPT)
+        dd_printf("\n");
+      out.close();
+    }
+  delete prompt_option;
+  delete null_prompt_option;
+  delete debug_option;
+}
+
+
+/*
+ * Output functions
+ */
+
+void
+cl_console::redirect(char *fname, char *mode)
+{
+  FILE *fp = fopen(fname, mode);
+  if (!fp)
+    dd_printf("Unable to open file '%s' for %s: %s\n",
+      fname, (mode[0]=='w') ? "write" : "append", strerror(errno));
+  out.set(fp, CH_FILE);
+}
+
+void
+cl_console::un_redirect(void)
+{
+  if (CH_UNDEF != rout.get_type())
+    out.close();
+}
+
+int
+cl_console::cmd_do_print(char *format, va_list ap)
+{
+  FILE *f = get_out()->get_fp();
+
+  if (f)
+   {
+      int ret = vfprintf(f, format, ap);
+      fflush(f);
+      return ret;
+    }
+  else
+    return 0;
+}
+
+/*
+ * Input functions
+ */
+
+char *
+cl_console::read_line(void)
+{
+#define BUF_LEN 1024
+
+  TRACE("%d-%s\n", get_id(), __PRETTY_FUNCTION__);
+
+  char *s = NULL;
+  FILE *fp = in.get_fp();
+  assert(fp);
+
+#ifdef HAVE_GETLINE
+  if (getline(&s, 0, fp) < 0)
+    return(0);
+#elif defined HAVE_GETDELIM
+  size_t n = BUF_LEN;
+  s = (char *)malloc(n);
+  if (getdelim(&s, &n, '\n', fp) < 0)
+    {
+      free(s);
+      return(0);
+    }
+#elif defined HAVE_FGETS
+  s = (char *)malloc(BUF_LEN);
+  if (fgets(s, BUF_LEN, fp) == NULL)
+    {
+      free(s);
+      return(0);
+    }
+#endif
+  s[strlen(s)-1]= '\0';
+  if (s[strlen(s)-1] == '\r')
+    s[strlen(s)-1]= '\0';
+  flags&= ~CONS_PROMPT;
+  return(s);
+}
+
+
+/*
+ * This console cl_listen_console on a socket and can accept connection requests
+ */
+
+cl_listen_console::cl_listen_console(int serverport, class cl_app *the_app)
+{
+  SOCKET sock;
+  app = the_app;
+
+  if (INVALID_SOCKET != (sock = make_server_socket(serverport)))
+    {
+      if (SOCKET_ERROR == listen(sock, 10))
+        fprintf(stderr, "Can't listen on port %d: %d\n", serverport, WSAGetLastError());
+    }
+  in.set((HANDLE)sock, CH_SOCKET);
+}
+
+int
+cl_listen_console::proc_input(class cl_cmdset *cmdset)
+{
+  class cl_commander_base *cmd = app->get_commander();
+
+  struct sockaddr_in sock_addr;
+  ACCEPT_SOCKLEN_T size = sizeof(struct sockaddr);
+  SOCKET newsock = accept((SOCKET)get_in_fd(), (struct sockaddr*)&sock_addr, &size);
+
+  if (INVALID_SOCKET == newsock)
+    {
+      fprintf(stderr, "Can't accept: %d\n", WSAGetLastError());
+      return(0);
+    }
+
+  int fh = _open_osfhandle((intptr_t)newsock, _O_TEXT);
+  if (-1 == fh)
+    {
+      fprintf(stderr, "Can't _open_osfhandle\n");
+    }
+  FILE *fp = fdopen(fh, "r");
+  if (!fp)
+    fprintf(stderr, "Can't open port for input\n");
+  cl_channel ch_in = cl_channel(fp, CH_SOCKET);
+
+  fh = _open_osfhandle((intptr_t)newsock, _O_TEXT);
+  if (-1 == fh)
+    {
+      fprintf(stderr, "Can't _open_osfhandle\n");
+    }
+  fp = fdopen(fh, "w");
+  if (!fp)
+    fprintf(stderr, "Can't open port for output\n");
+  cl_channel ch_out = cl_channel(fp, CH_SOCKET);
+
+  class cl_console_base *c = new cl_console(ch_in, ch_out, app);
+  c->flags |= CONS_INTERACTIVE;
+  cmd->add_console(c);
+
+  return 0;
+}
+
+
+/*
+ * Sub-console
+ */
+
+cl_sub_console::cl_sub_console(class cl_console_base *the_parent,
+  cl_channel _in, cl_channel _out, class cl_app *the_app):
+  cl_console(_in, _out, 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();
+  flags |= CONS_ECHO;
+  return 0;
+}
+
+
+/*
+ * Command interpreter
+ *____________________________________________________________________________
+ */
+
+int
+cl_commander::init(void)
+{
+  TRACE("%s\n", __PRETTY_FUNCTION__);
+
+  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;
+
+  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");
+
+  bool need_config = DD_TRUE;
+
+  if (port_number_option.use("port_number"))
+    add_console(new cl_listen_console(port_number_option.get_value((long)0), app));
+
+  /* The following code is commented out because it produces gcc warnings
+   * newcmd.cc: In member function `virtual int cl_commander::init()':
+   * newcmd.cc:785: warning: 'Config' might be used uninitialized in this function
+   * newcmd.cc:786: warning: 'cn' might be used uninitialized in this function
+   */
+  /*
+  char *Config= config_file_option.get_value(Config);
+  char *cn= console_on_option.get_value(cn);
+   */
+  /* Here shoud probably be something else, but is still better then the former code... */
+  char *Config = config_file_option.get_value("");
+  char *cn = console_on_option.get_value("");
+
+  if (cn)
+    {
+      add_console(con = new cl_console(cn, cn, app));
+      exec_on(con, Config);
+      need_config = DD_FALSE;
+    }
+  if (cons->get_count() == 0)
+    {
+      add_console(con = new cl_console(stdin, stdout, app));
+      exec_on(con, Config);
+      need_config = DD_FALSE;
+    }
+  if (need_config && Config && *Config)
+    {
+      FILE *fc = fopen(Config, "r");
+      if (!fc)
+        fprintf(stderr, "Can't open `%s': %s\n", Config, strerror(errno));
+      else
+        {
+          con = new cl_console(fc, stderr, app);
+          con->flags |= CONS_NOWELCOME | CONS_ECHO;
+          add_console(con);
+        }
+    }
+  return(0);
+}
+
+void
+cl_commander::set_fd_set(void)
+{
+  TRACE("%s\n", __PRETTY_FUNCTION__);
+
+  int i;
+
+  FD_ZERO(&read_set);
+
+  for (i = 0; i < cons->count; i++)
+    {
+      class cl_console *c= dynamic_cast<class cl_console*>((class cl_console_base*)(cons->at(i)));
+
+      if (c->input_active() && CH_SOCKET == c->in.get_type())
+        {
+          HANDLE fd = c->get_in_fd();
+          assert(INVALID_HANDLE_VALUE != fd);
+
+          FD_SET((SOCKET)fd, &read_set);
+        }
+    }
+}
+
+int
+cl_commander::console_count(void)
+{
+  int i = 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)));
+
+      if (c->input_active())
+        {
+          switch (c->in.get_type())
+            {
+            case CH_CONSOLE:
+            case CH_FILE:
+            case CH_SERIAL:
+              ++i;
+              break;
+
+            default:
+              break;
+            }
+        }
+    }
+
+  return i;
+}
+
+int
+cl_commander::console_input_avail(void)
+{
+  int i = 0;
+
+  FD_ZERO(&console_active_set);
+  for (int j = 0; j < cons->count; j++)
+    {
+      class cl_console *c = dynamic_cast<class cl_console*>((class cl_console_base*)(cons->at(j)));
+
+      if (c->input_avail())
+        {
+          HANDLE fd = c->get_in_fd();
+          assert(INVALID_HANDLE_VALUE != fd);
+
+          switch (c->in.get_type())
+            {
+            case CH_CONSOLE:
+            case CH_FILE:
+            case CH_SERIAL:
+              FD_SET((SOCKET)fd, &console_active_set);
+              ++i;
+              break;
+
+            default:
+              break;
+            }
+        }
+    }
+
+  return i;
+}
+
+int
+cl_commander::socket_input_avail(long timeout, bool sleep)
+{
+  active_set = read_set;
+
+  if (active_set.fd_count)
+    {
+      struct timeval tv = {0, 0};
+
+      struct timeval *tvp = sleep ? NULL : &tv;
+
+      int i = select(0, &active_set, NULL, NULL, tvp);
+      if (SOCKET_ERROR == i)
+        {
+          fprintf(stderr, "Can't select: %d\n", WSAGetLastError());
+          return 0;
+        }
+
+      return i;
+    }
+  else
+    {
+      Sleep(timeout / 1000);
+      return 0;
+    }
+}
+
+int
+cl_commander::input_avail_timeout(long timeout)
+{
+  TRACE("%s\n", __PRETTY_FUNCTION__);
+
+  int n;
+  if (0 != (n = console_input_avail()))
+    FD_ZERO(&active_set);
+  else
+       n = socket_input_avail(timeout, false);
+
+  return n;
+}
+
+#define CONSOLE_TIMEOUT 300000
+
+int
+cl_commander::wait_input(void)
+{
+  TRACE("%s\n", __PRETTY_FUNCTION__);
+
+  prompt();
+
+  if (0 < console_count())
+    {
+      int n;
+
+      while (0 == (n = input_avail_timeout(CONSOLE_TIMEOUT)))
+        ;
+
+      return n;
+    }
+  else
+    {
+      FD_ZERO(&console_active_set);
+      return socket_input_avail(0, true);
+    }
+}
+
+int
+cl_commander::proc_input(void)
+{
+  TRACE("%s\n", __PRETTY_FUNCTION__);
+
+  for (int j = 0; j < cons->count; j++)
+    {
+      class cl_console *c = dynamic_cast<class cl_console*>((class cl_console_base*)(cons->at(j)));
+
+      if (c->input_active())
+        {
+          HANDLE fd = c->get_in_fd();
+          assert(INVALID_HANDLE_VALUE != fd);
+
+          if (FD_ISSET(fd, &active_set) || FD_ISSET(fd, &console_active_set))
+            {
+              actual_console = c;
+              if (c->proc_input(cmdset))
+                {
+                  del_console(c);
+                  delete c;
+                }
+              actual_console = 0;
+              return 0 == cons->count;
+            }
+        }
+    }
+  return 0;
+}
+
+
+/* End of cmd.src/newcmdwin32.cc */