* sim/ucsim/cmd.src/newcmdposix.cc, sim/ucsim/cmd.src/newcmdposixcl.h,
[fw/sdcc] / sim / ucsim / cmd.src / cmdutil.cc
index 083b84562d73e8d793633e1fd405c61225414b1f..c6820e9baedeb43272ef08db018e8ea23e427019 100644 (file)
@@ -1,8 +1,9 @@
 /*
- * Simulator of microcontrollers (cmdutil.cc)
+ * Simulator of microcontrollers (cmd.src/cmdutil.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
  *
  */
@@ -30,17 +31,25 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
+#include <assert.h>
 #include <sys/types.h>
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-# include <netinet/in.h>
-# include <arpa/inet.h>
+#ifdef SOCKET_AVAIL
+# include HEADER_SOCKET
+# if defined HAVE_SYS_SOCKET_H
+#  include <netinet/in.h>
+#  include <arpa/inet.h>
+# endif
+#endif
+#ifdef _WIN32
+#include <malloc.h>
 #endif
+
 #include "i_string.h"
 
 #include "stypes.h"
 #include "globals.h"
 #include "uccl.h"
+#include "cmdutil.h"
 
 
 /*
@@ -48,12 +57,59 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  */
 
 #ifdef SOCKET_AVAIL
+#ifdef _WIN32
+static void
+init_winsock(void)
+{
+  static bool is_initialized = false;
+
+  if (!is_initialized)
+    {
+      WSADATA wsaData;
+
+      // Initialize Winsock
+      int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
+      if (iResult != 0)
+        {
+          printf("WSAStartup failed: %d\n", iResult);
+          exit(1);
+        }
+    }
+}
+
+SOCKET
+make_server_socket(unsigned short int port)
+{
+  init_winsock();
+
+  struct sockaddr_in name;
+
+  /* Create the socket. */
+  SOCKET sock = WSASocket(PF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
+  if (INVALID_SOCKET == sock)
+    {
+      fprintf(stderr, "socket: %d\n", WSAGetLastError());
+      return INVALID_SOCKET;
+    }
+
+  name.sin_family     = AF_INET;
+  name.sin_port       = htons(port);
+  name.sin_addr.s_addr= htonl(INADDR_ANY);
+  if (SOCKET_ERROR == bind(sock, (struct sockaddr *)&name, sizeof(name)))
+    {
+      fprintf(stderr, "bind: %d\n", WSAGetLastError());
+      return INVALID_SOCKET;
+    }
+
+  return sock;
+}
+#else
 int
 make_server_socket(unsigned short int port)
 {
   int sock, i;
   struct sockaddr_in name;
-     
+
   /* Create the socket. */
   sock= socket(PF_INET, SOCK_STREAM, 0);
   if (sock < 0)
@@ -61,7 +117,7 @@ make_server_socket(unsigned short int port)
       perror("socket");
       return(0);
     }
-     
+
   /* Give the socket a name. */
   i= 1;
   if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&i, sizeof(i)) < 0)
@@ -80,25 +136,142 @@ make_server_socket(unsigned short int port)
   return(sock);
 }
 #endif
+#endif
+
+#if _WIN32
+enum e_handle_type
+get_handle_type(HANDLE handle)
+{
+  DWORD file_type = GetFileType(handle);
 
+  switch (file_type)
+    {
+    case FILE_TYPE_CHAR:
+      {
+              DWORD err;
 
-/*
- * Printing out an integer in binary format
- */
+        if (!ClearCommError(handle, &err, NULL))
+          { 
+            if (ERROR_INVALID_HANDLE == GetLastError())
+              return CH_CONSOLE;
+          }
+      }
+      return CH_SERIAL;
 
-void
-print_bin(long data, int bits, FILE *f)
+    case FILE_TYPE_DISK:
+      return CH_FILE;
+    }
+
+  char sockbuf[256];
+  int optlen = sizeof(sockbuf);
+
+  if (SOCKET_ERROR != getsockopt((SOCKET)handle, SOL_SOCKET, SO_TYPE, sockbuf, &optlen) ||
+    WSAENOTSOCK != WSAGetLastError())
+    return CH_SOCKET;
+
+  assert(false);
+  return CH_UNDEF;
+}
+
+bool
+input_avail(HANDLE handle, e_handle_type type)
 {
-  long mask= 1;
+  if (CH_UNDEF == type)
+      type = get_handle_type(handle);
 
-  mask= mask << ((bits >= 1)?(bits-1):0);
-  while (bits--)
+  switch (type)
     {
-      fprintf(f, "%c", (data&mask)?'1':'0');
-      mask>>= 1;
+    case CH_SOCKET:
+      {
+        struct timeval tv = {0, 0};
+
+        assert(INVALID_HANDLE_VALUE != handle);
+
+        fd_set s;
+        FD_ZERO(&s);
+        FD_SET((SOCKET)handle, &s);
+
+        int ret = select(0, &s, NULL, NULL, &tv);
+        if (SOCKET_ERROR == ret)
+          fprintf(stderr, "Can't select: %d\n", WSAGetLastError());
+
+        return ret != SOCKET_ERROR && ret != 0;
+      }
+
+    case CH_FILE:
+      return true;
+
+    case CH_CONSOLE:
+      {
+        PINPUT_RECORD pIRBuf;
+        DWORD NumPending;
+        DWORD NumPeeked;
+
+        /*
+         * Peek all pending console events
+         */
+        if (INVALID_HANDLE_VALUE == handle ||
+          !GetNumberOfConsoleInputEvents(handle, &NumPending) ||
+          NumPending == 0 ||
+          NULL == (pIRBuf = (PINPUT_RECORD)_alloca(NumPending * sizeof(INPUT_RECORD))))
+          return FALSE;
+
+        if (PeekConsoleInput(handle, pIRBuf, NumPending, &NumPeeked) &&
+          NumPeeked != 0L &&
+          NumPeeked <= NumPending)
+          {
+
+            /*
+             * Scan all of the peeked events to determine if any is a key event
+             * which should be recognized.
+             */
+            for ( ; NumPeeked > 0 ; NumPeeked--, pIRBuf++ )
+              {
+                if (KEY_EVENT == pIRBuf->EventType &&
+                  pIRBuf->Event.KeyEvent.bKeyDown &&
+                  pIRBuf->Event.KeyEvent.uChar.AsciiChar)
+                  return true;
+              }
+          }
+
+        return false;
+      }
+
+    case CH_SERIAL:
+      {
+        DWORD err;
+        COMSTAT comStat;
+
+        bool res = ClearCommError(handle, &err, &comStat);
+        assert(res);
+
+        return res ? comStat.cbInQue > 0 : false;
+      }
+
+    default:
+      assert(false);
+      return false;
     }
 }
+#else
+bool
+input_avail(UCSOCKET_T fd)
+{
+  assert(0 <= fd);
+
+  fd_set s;
+  FD_ZERO(&s);
+  FD_SET(fd, &s);
 
+  struct timeval tv = {0, 0};
+
+  int i = select(fd + 1, &s, NULL, NULL, &tv);
+  if (i < 0)
+    perror("select");
+
+  return i > 0;
+}
+#endif
 
 /*
  * Searching for a name in the specified table
@@ -110,15 +283,22 @@ get_name_entry(struct name_entry tabl[], char *name, class cl_uc *uc)
   int i= 0;
   char *p;
 
+  if (!tabl ||
+      !name ||
+      !(*name))
+    return(0);
   for (p= name; *p; *p= toupper(*p), p++);
   while (tabl[i].name &&
-        (!(tabl[i].cpu_type & uc->type) ||
-        (strcmp(tabl[i].name, name) != 0)))
-    i++;
+         (!(tabl[i].cpu_type & uc->type) ||
+         (strcmp(tabl[i].name, name) != 0)))
+    {
+      //printf("tabl[%d].name=%s <-> %s\n",i,tabl[i].name,name);
+      i++;
+    }
   if (tabl[i].name != NULL)
     return(&tabl[i]);
   else
-    return(NULL);
+    return(0);
 }
 
 
@@ -126,83 +306,84 @@ get_name_entry(struct name_entry tabl[], char *name, class cl_uc *uc)
  * Interpreting a bitname
  */
 
-bool
+/*bool
 interpret_bitname(char *name, class cl_uc *uc,
-                 uchar **cell, uchar *celladdr,
-                 uchar *bitaddr, uchar *bitmask,
-                 char **symname)
+                  uchar **cell, uchar *celladdr,
+                  uchar *bitaddr, uchar *bitmask,
+                  char **symname)
 {
   char *dot, *p;
   char *sym, bitnumstr[2];
   struct name_entry *ne;
   int bitnum, i;
-  
+
   if ((dot= strchr(name, '.')) != NULL)
     {
       *dot++= '\0';
       if ((ne= get_name_entry(uc->sfr_tbl(), name, uc)) == NULL)
-       {
-         *celladdr= strtol(name, &p, 0);
-         if (p && *p)
-           {
-             dot--;
-             *dot= '.';
-             return(FALSE);
-           }
-       }
+        {
+          *celladdr= strtol(name, &p, 0);
+          if (p && *p)
+            {
+              dot--;
+              *dot= '.';
+              return(DD_FALSE);
+            }
+        }
       else
-       *celladdr= ne->addr;
+        *celladdr= ne->addr;
       if ((*celladdr < 0x20) ||
-         ((*celladdr > 0x2f) && (*celladdr < 0x80)) ||
-         ((*celladdr > 0x7f) && (*celladdr & 0x07)))
-       return(FALSE);
+          ((*celladdr > 0x2f) && (*celladdr < 0x80)) ||
+          ((*celladdr > 0x7f) && (*celladdr & 0x07)))
+        return(DD_FALSE);
       bitnum= strtol(dot, &p, 0);
       if ((p && *p) ||
-         (bitnum < 0) ||
-         (bitnum > 7))
-       return(FALSE);
+          (bitnum < 0) ||
+          (bitnum > 7))
+        return(DD_FALSE);
       if (*celladdr > 0x7f)
-       *bitaddr= *celladdr + bitnum;
+        *bitaddr= *celladdr + bitnum;
       else
-       *bitaddr= (*celladdr - 0x20)*8 + bitnum;
+        *bitaddr= (*celladdr - 0x20)*8 + bitnum;
       dot--;
       *dot= '.';
     }
   else
     {
       if ((ne= get_name_entry(uc->bit_tbl(), name, uc)) == NULL)
-       {
-         *bitaddr= strtol(name, &p, 0);
-         if ((p && *p) ||
-             (*bitaddr > 0xff))
-           return(FALSE);
-       }
+        {
+          *bitaddr= strtol(name, &p, 0);
+          if ((p && *p) ||
+              (*bitaddr > 0xff))
+            return(DD_FALSE);
+        }
       else
-       *bitaddr= ne->addr;
+        *bitaddr= ne->addr;
       if (*bitaddr > 0x7f)
-       *celladdr= *bitaddr & 0xf8;
+        *celladdr= *bitaddr & 0xf8;
       else
-       *celladdr= (*bitaddr >> 3) + 0x20;
+        *celladdr= (*bitaddr >> 3) + 0x20;
     }
   // *bitaddr, *celladdr now OK
-  *cell= uc->get_bit/*FIXME*/(*bitaddr);
+  *cell= uc->get_bit//FIXME
+    (*bitaddr);
   *bitmask= BIT_MASK(*bitaddr);
   // making symbolic name
   if (!symname)
-    return(TRUE);
+    return(DD_TRUE);
   i= 0;
   while (uc->bit_tbl()[i].name &&
-        (uc->bit_tbl()[i].addr != *bitaddr))
+         (uc->bit_tbl()[i].addr != *bitaddr))
     i++;
   if (uc->bit_tbl()[i].name)
     {
       sym= strdup(uc->bit_tbl()[i].name);
       *symname= sym;
-      return(TRUE);
+      return(DD_TRUE);
     }
   i= 0;
   while (uc->sfr_tbl()[i].name &&
-        (uc->sfr_tbl()[i].addr != *celladdr))
+         (uc->sfr_tbl()[i].addr != *celladdr))
     i++;
   if (uc->sfr_tbl()[i].name)
     sym= strdup(uc->sfr_tbl()[i].name);
@@ -216,8 +397,8 @@ interpret_bitname(char *name, class cl_uc *uc,
   sprintf(bitnumstr, "%1d", *bitaddr & 0x07);
   strcat(sym, bitnumstr);
   *symname= sym;
-  return(TRUE);
-}
+  return(DD_TRUE);
+}*/
 
 
 /*
@@ -227,8 +408,8 @@ interpret_bitname(char *name, class cl_uc *uc,
 char *
 proc_escape(char *string, int *len)
 {
-  char  spec_chars[]= "fnrtvab";
-  char  spec[]= "\f\n\r\t\v\a\b";
+  char  spec_chars[]= "fnrtvab\"";
+  char  spec[]= "\f\n\r\t\v\a\b\"";
   char  *s, *str, *p;
 
   s  = string;
@@ -239,43 +420,43 @@ proc_escape(char *string, int *len)
       char *spec_c;
 
       if (*s == '\\' &&
-         *(s+1))
-       {
-         s++;
-         if (*s == '0')
-           {
-             if (!isdigit(*(s+1)))
-               {
-                 *p++= '\0';
-                 s++;
-               }
-             else
-               {
-                 char *octal, *chk, data;
-                 int i, j;
-                 i= strspn(s, "01234567");
-                 octal= (char *)malloc(i+1);
-                 j= 0;
-                 while (*s &&
-                        (j < i))
-                   octal[j++]= *s++;
-                 octal[j]= '\0';
-                 data= strtol(octal, &chk, 8);
-                 if (!chk || !(*chk))
-                   *p++= data;
-               }
-           }
-         else
-           if ((spec_c= strchr(spec_chars, *s)) != NULL)
-             {
-               *p++= spec[spec_c-spec_chars];
-               s++;
-             }
-           else
-             *p++= *s++;
-       }
+          *(s+1))
+        {
+          s++;
+          if (*s == '0')
+            {
+              if (!isdigit(*(s+1)))
+                {
+                  *p++= '\0';
+                  s++;
+                }
+              else
+                {
+                  char *octal, *chk, data;
+                  int i, j;
+                  i= strspn(s, "01234567");
+                  octal= (char *)malloc(i+1);
+                  j= 0;
+                  while (*s &&
+                         (j < i))
+                    octal[j++]= *s++;
+                  octal[j]= '\0';
+                  data= strtol(octal, &chk, 8);
+                  if (!chk || !(*chk))
+                    *p++= data;
+                }
+            }
+          else
+            if ((spec_c= strchr(spec_chars, *s)) != NULL)
+              {
+                *p++= spec[spec_c-spec_chars];
+                s++;
+              }
+            else
+              *p++= *s++;
+        }
       else
-       *p++= *s++;
+        *p++= *s++;
     }
   *p= '\0';
   *len= p-str;
@@ -283,4 +464,4 @@ proc_escape(char *string, int *len)
 }
 
 
-/* End of cmdutil.cc */
+/* End of cmd.src/cmdutil.cc */