* sim/ucsim/cmd.src/cmdutil.cc: #include <sys/time.h> and <unistd.h>
[fw/sdcc] / sim / ucsim / cmd.src / cmdutil.cc
1 /*
2  * Simulator of microcontrollers (cmd.src/cmdutil.cc)
3  *
4  * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
5  * Copyright (C) 2006, Borut Razem - borut.razem@siol.net
6  *
7  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
8  *
9  */
10
11 /* This file is part of microcontroller simulator: ucsim.
12
13 UCSIM is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 UCSIM is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with UCSIM; see the file COPYING.  If not, write to the Free
25 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 02111-1307, USA. */
27 /*@1@*/
28
29 #include "ddconfig.h"
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <ctype.h>
34 #include <assert.h>
35 #include <sys/time.h>
36 #include <sys/types.h>
37 #ifdef SOCKET_AVAIL
38 # include HEADER_SOCKET
39 # if defined HAVE_SYS_SOCKET_H
40 #  include <netinet/in.h>
41 #  include <arpa/inet.h>
42 # endif
43 #endif
44 #ifdef HAVE_UNISTD_H
45 #include <unistd.h>
46 #endif
47 #ifdef _WIN32
48 #include <malloc.h>
49 #endif
50
51 #include "i_string.h"
52
53 #include "stypes.h"
54 #include "globals.h"
55 #include "uccl.h"
56 #include "cmdutil.h"
57
58
59 /*
60  * Making a socket which can be used to listen for a specified port
61  */
62
63 #ifdef SOCKET_AVAIL
64 #ifdef _WIN32
65 static void
66 init_winsock(void)
67 {
68   static bool is_initialized = false;
69
70   if (!is_initialized)
71     {
72       WSADATA wsaData;
73
74       // Initialize Winsock
75       int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
76       if (iResult != 0)
77         {
78           printf("WSAStartup failed: %d\n", iResult);
79           exit(1);
80         }
81     }
82 }
83
84 SOCKET
85 make_server_socket(unsigned short int port)
86 {
87   init_winsock();
88
89   struct sockaddr_in name;
90
91   /* Create the socket. */
92   SOCKET sock = WSASocket(PF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
93   if (INVALID_SOCKET == sock)
94     {
95       fprintf(stderr, "socket: %d\n", WSAGetLastError());
96       return INVALID_SOCKET;
97     }
98
99   name.sin_family     = AF_INET;
100   name.sin_port       = htons(port);
101   name.sin_addr.s_addr= htonl(INADDR_ANY);
102   if (SOCKET_ERROR == bind(sock, (struct sockaddr *)&name, sizeof(name)))
103     {
104       fprintf(stderr, "bind: %d\n", WSAGetLastError());
105       return INVALID_SOCKET;
106     }
107
108   return sock;
109 }
110 #else
111 int
112 make_server_socket(unsigned short int port)
113 {
114   int sock, i;
115   struct sockaddr_in name;
116
117   /* Create the socket. */
118   sock= socket(PF_INET, SOCK_STREAM, 0);
119   if (sock < 0)
120     {
121       perror("socket");
122       return(0);
123     }
124
125   /* Give the socket a name. */
126   i= 1;
127   if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&i, sizeof(i)) < 0)
128     {
129       perror("setsockopt");
130     }
131   name.sin_family     = AF_INET;
132   name.sin_port       = htons(port);
133   name.sin_addr.s_addr= htonl(INADDR_ANY);
134   if (bind(sock, (struct sockaddr *)&name, sizeof(name)) < 0)
135     {
136       perror("bind");
137       return(0);
138     }
139
140   return(sock);
141 }
142 #endif
143 #endif
144
145 #if _WIN32
146 enum e_handle_type
147 get_handle_type(HANDLE handle)
148 {
149   DWORD file_type = GetFileType(handle);
150
151   switch (file_type)
152     {
153     case FILE_TYPE_CHAR:
154       {
155               DWORD err;
156
157         if (!ClearCommError(handle, &err, NULL))
158           { 
159             if (ERROR_INVALID_HANDLE == GetLastError())
160               return CH_CONSOLE;
161           }
162       }
163       return CH_SERIAL;
164
165     case FILE_TYPE_DISK:
166       return CH_FILE;
167     }
168
169   char sockbuf[256];
170   int optlen = sizeof(sockbuf);
171
172   if (SOCKET_ERROR != getsockopt((SOCKET)handle, SOL_SOCKET, SO_TYPE, sockbuf, &optlen) ||
173     WSAENOTSOCK != WSAGetLastError())
174     return CH_SOCKET;
175
176   assert(false);
177   return CH_UNDEF;
178 }
179
180 bool
181 input_avail(HANDLE handle, e_handle_type type)
182 {
183   if (CH_UNDEF == type)
184       type = get_handle_type(handle);
185
186   switch (type)
187     {
188     case CH_SOCKET:
189       {
190         struct timeval tv = {0, 0};
191
192         assert(INVALID_HANDLE_VALUE != handle);
193
194         fd_set s;
195         FD_ZERO(&s);
196         FD_SET((SOCKET)handle, &s);
197
198         int ret = select(0, &s, NULL, NULL, &tv);
199         if (SOCKET_ERROR == ret)
200           fprintf(stderr, "Can't select: %d\n", WSAGetLastError());
201
202         return ret != SOCKET_ERROR && ret != 0;
203       }
204
205     case CH_FILE:
206       return true;
207
208     case CH_CONSOLE:
209       {
210         PINPUT_RECORD pIRBuf;
211         DWORD NumPending;
212         DWORD NumPeeked;
213
214         /*
215          * Peek all pending console events
216          */
217         if (INVALID_HANDLE_VALUE == handle ||
218           !GetNumberOfConsoleInputEvents(handle, &NumPending) ||
219           NumPending == 0 ||
220           NULL == (pIRBuf = (PINPUT_RECORD)_alloca(NumPending * sizeof(INPUT_RECORD))))
221           return FALSE;
222
223         if (PeekConsoleInput(handle, pIRBuf, NumPending, &NumPeeked) &&
224           NumPeeked != 0L &&
225           NumPeeked <= NumPending)
226           {
227
228             /*
229              * Scan all of the peeked events to determine if any is a key event
230              * which should be recognized.
231              */
232             for ( ; NumPeeked > 0 ; NumPeeked--, pIRBuf++ )
233               {
234                 if (KEY_EVENT == pIRBuf->EventType &&
235                   pIRBuf->Event.KeyEvent.bKeyDown &&
236                   pIRBuf->Event.KeyEvent.uChar.AsciiChar)
237                   return true;
238               }
239           }
240
241         return false;
242       }
243
244     case CH_SERIAL:
245       {
246         DWORD err;
247         COMSTAT comStat;
248
249         bool res = ClearCommError(handle, &err, &comStat);
250         assert(res);
251
252         return res ? comStat.cbInQue > 0 : false;
253       }
254
255     default:
256       assert(false);
257       return false;
258     }
259 }
260 #else
261 bool
262 input_avail(UCSOCKET_T fd)
263 {
264   assert(0 <= fd);
265
266   fd_set s;
267   FD_ZERO(&s);
268   FD_SET(fd, &s);
269
270   struct timeval tv = {0, 0};
271
272   int i = select(fd + 1, &s, NULL, NULL, &tv);
273   if (i < 0)
274     perror("select");
275
276   return i > 0;
277 }
278 #endif
279
280 /*
281  * Searching for a name in the specified table
282  */
283
284 struct name_entry *
285 get_name_entry(struct name_entry tabl[], char *name, class cl_uc *uc)
286 {
287   int i= 0;
288   char *p;
289
290   if (!tabl ||
291       !name ||
292       !(*name))
293     return(0);
294   for (p= name; *p; *p= toupper(*p), p++);
295   while (tabl[i].name &&
296          (!(tabl[i].cpu_type & uc->type) ||
297          (strcmp(tabl[i].name, name) != 0)))
298     {
299       //printf("tabl[%d].name=%s <-> %s\n",i,tabl[i].name,name);
300       i++;
301     }
302   if (tabl[i].name != NULL)
303     return(&tabl[i]);
304   else
305     return(0);
306 }
307
308
309 /*
310  * Interpreting a bitname
311  */
312
313 /*bool
314 interpret_bitname(char *name, class cl_uc *uc,
315                   uchar **cell, uchar *celladdr,
316                   uchar *bitaddr, uchar *bitmask,
317                   char **symname)
318 {
319   char *dot, *p;
320   char *sym, bitnumstr[2];
321   struct name_entry *ne;
322   int bitnum, i;
323
324   if ((dot= strchr(name, '.')) != NULL)
325     {
326       *dot++= '\0';
327       if ((ne= get_name_entry(uc->sfr_tbl(), name, uc)) == NULL)
328         {
329           *celladdr= strtol(name, &p, 0);
330           if (p && *p)
331             {
332               dot--;
333               *dot= '.';
334               return(DD_FALSE);
335             }
336         }
337       else
338         *celladdr= ne->addr;
339       if ((*celladdr < 0x20) ||
340           ((*celladdr > 0x2f) && (*celladdr < 0x80)) ||
341           ((*celladdr > 0x7f) && (*celladdr & 0x07)))
342         return(DD_FALSE);
343       bitnum= strtol(dot, &p, 0);
344       if ((p && *p) ||
345           (bitnum < 0) ||
346           (bitnum > 7))
347         return(DD_FALSE);
348       if (*celladdr > 0x7f)
349         *bitaddr= *celladdr + bitnum;
350       else
351         *bitaddr= (*celladdr - 0x20)*8 + bitnum;
352       dot--;
353       *dot= '.';
354     }
355   else
356     {
357       if ((ne= get_name_entry(uc->bit_tbl(), name, uc)) == NULL)
358         {
359           *bitaddr= strtol(name, &p, 0);
360           if ((p && *p) ||
361               (*bitaddr > 0xff))
362             return(DD_FALSE);
363         }
364       else
365         *bitaddr= ne->addr;
366       if (*bitaddr > 0x7f)
367         *celladdr= *bitaddr & 0xf8;
368       else
369         *celladdr= (*bitaddr >> 3) + 0x20;
370     }
371   // *bitaddr, *celladdr now OK
372   *cell= uc->get_bit//FIXME
373     (*bitaddr);
374   *bitmask= BIT_MASK(*bitaddr);
375   // making symbolic name
376   if (!symname)
377     return(DD_TRUE);
378   i= 0;
379   while (uc->bit_tbl()[i].name &&
380          (uc->bit_tbl()[i].addr != *bitaddr))
381     i++;
382   if (uc->bit_tbl()[i].name)
383     {
384       sym= strdup(uc->bit_tbl()[i].name);
385       *symname= sym;
386       return(DD_TRUE);
387     }
388   i= 0;
389   while (uc->sfr_tbl()[i].name &&
390          (uc->sfr_tbl()[i].addr != *celladdr))
391     i++;
392   if (uc->sfr_tbl()[i].name)
393     sym= strdup(uc->sfr_tbl()[i].name);
394   else
395     {
396       sym= (char *)malloc(3);
397       sprintf(sym, "%02x", *celladdr);
398     }
399   sym= (char *)realloc(sym, strlen(sym)+2);
400   strcat(sym, ".");
401   sprintf(bitnumstr, "%1d", *bitaddr & 0x07);
402   strcat(sym, bitnumstr);
403   *symname= sym;
404   return(DD_TRUE);
405 }*/
406
407
408 /*
409  * Processing escape sequencies in a string
410  */
411
412 char *
413 proc_escape(char *string, int *len)
414 {
415   char  spec_chars[]= "fnrtvab\"";
416   char  spec[]= "\f\n\r\t\v\a\b\"";
417   char  *s, *str, *p;
418
419   s  = string;
420   str= (char *)malloc(strlen(string)+1);
421   p  = str;
422   while (*s)
423     {
424       char *spec_c;
425
426       if (*s == '\\' &&
427           *(s+1))
428         {
429           s++;
430           if (*s == '0')
431             {
432               if (!isdigit(*(s+1)))
433                 {
434                   *p++= '\0';
435                   s++;
436                 }
437               else
438                 {
439                   char *octal, *chk, data;
440                   int i, j;
441                   i= strspn(s, "01234567");
442                   octal= (char *)malloc(i+1);
443                   j= 0;
444                   while (*s &&
445                          (j < i))
446                     octal[j++]= *s++;
447                   octal[j]= '\0';
448                   data= strtol(octal, &chk, 8);
449                   if (!chk || !(*chk))
450                     *p++= data;
451                 }
452             }
453           else
454             if ((spec_c= strchr(spec_chars, *s)) != NULL)
455               {
456                 *p++= spec[spec_c-spec_chars];
457                 s++;
458               }
459             else
460               *p++= *s++;
461         }
462       else
463         *p++= *s++;
464     }
465   *p= '\0';
466   *len= p-str;
467   return(str);
468 }
469
470
471 /* End of cmd.src/cmdutil.cc */