d27a335fb1f88c05100efafacd338b7ca27f0d67
[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  * 
6  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
7  *
8  */
9
10 /* This file is part of microcontroller simulator: ucsim.
11
12 UCSIM is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 UCSIM is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with UCSIM; see the file COPYING.  If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 02111-1307, USA. */
26 /*@1@*/
27
28 #include "ddconfig.h"
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <ctype.h>
33 #include <sys/types.h>
34 #ifdef _WIN32
35 # include <winsock23.h>
36 # define SOCKET_AVAIL
37 #elif defined HAVE_SYS_SOCKET_H
38 # include <sys/socket.h>
39 # include <netinet/in.h>
40 # include <arpa/inet.h>
41 #endif
42 #include "i_string.h"
43
44 #include "stypes.h"
45 #include "globals.h"
46 #include "uccl.h"
47
48
49 /*
50  * Making a socket which can be used to listen for a specified port
51  */
52
53 #ifdef SOCKET_AVAIL
54 int
55 make_server_socket(unsigned short int port)
56 {
57   int sock, i;
58   struct sockaddr_in name;
59      
60   /* Create the socket. */
61   sock= socket(PF_INET, SOCK_STREAM, 0);
62   if (sock < 0)
63     {
64       perror("socket");
65       return(0);
66     }
67      
68   /* Give the socket a name. */
69   i= 1;
70   if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&i, sizeof(i)) < 0)
71     {
72       perror("setsockopt");
73     }
74   name.sin_family     = AF_INET;
75   name.sin_port       = htons(port);
76   name.sin_addr.s_addr= htonl(INADDR_ANY);
77   if (bind(sock, (struct sockaddr *)&name, sizeof(name)) < 0)
78     {
79       perror("bind");
80       return(0);
81     }
82
83   return(sock);
84 }
85 #endif
86
87
88 /*
89  * Printing out an integer in binary format
90  */
91
92 /*void
93 print_bin(long data, int bits, class cl_console *con)
94 {
95   long mask= 1;
96
97   mask= mask << ((bits >= 1)?(bits-1):0);
98   while (bits--)
99     {
100       con->printf("%c", (data&mask)?'1':'0');
101       mask>>= 1;
102     }
103 }*/
104
105
106 /*
107  * Searching for a name in the specified table
108  */
109
110 struct name_entry *
111 get_name_entry(struct name_entry tabl[], char *name, class cl_uc *uc)
112 {
113   int i= 0;
114   char *p;
115
116   if (!tabl ||
117       !name ||
118       !(*name))
119     return(0);
120   for (p= name; *p; *p= toupper(*p), p++);
121   while (tabl[i].name &&
122          (!(tabl[i].cpu_type & uc->type) ||
123          (strcmp(tabl[i].name, name) != 0)))
124     {
125       //printf("tabl[%d].name=%s <-> %s\n",i,tabl[i].name,name);
126       i++;
127     }
128   if (tabl[i].name != NULL)
129     return(&tabl[i]);
130   else
131     return(0);
132 }
133
134
135 /*
136  * Interpreting a bitname
137  */
138
139 /*bool
140 interpret_bitname(char *name, class cl_uc *uc,
141                   uchar **cell, uchar *celladdr,
142                   uchar *bitaddr, uchar *bitmask,
143                   char **symname)
144 {
145   char *dot, *p;
146   char *sym, bitnumstr[2];
147   struct name_entry *ne;
148   int bitnum, i;
149   
150   if ((dot= strchr(name, '.')) != NULL)
151     {
152       *dot++= '\0';
153       if ((ne= get_name_entry(uc->sfr_tbl(), name, uc)) == NULL)
154         {
155           *celladdr= strtol(name, &p, 0);
156           if (p && *p)
157             {
158               dot--;
159               *dot= '.';
160               return(DD_FALSE);
161             }
162         }
163       else
164         *celladdr= ne->addr;
165       if ((*celladdr < 0x20) ||
166           ((*celladdr > 0x2f) && (*celladdr < 0x80)) ||
167           ((*celladdr > 0x7f) && (*celladdr & 0x07)))
168         return(DD_FALSE);
169       bitnum= strtol(dot, &p, 0);
170       if ((p && *p) ||
171           (bitnum < 0) ||
172           (bitnum > 7))
173         return(DD_FALSE);
174       if (*celladdr > 0x7f)
175         *bitaddr= *celladdr + bitnum;
176       else
177         *bitaddr= (*celladdr - 0x20)*8 + bitnum;
178       dot--;
179       *dot= '.';
180     }
181   else
182     {
183       if ((ne= get_name_entry(uc->bit_tbl(), name, uc)) == NULL)
184         {
185           *bitaddr= strtol(name, &p, 0);
186           if ((p && *p) ||
187               (*bitaddr > 0xff))
188             return(DD_FALSE);
189         }
190       else
191         *bitaddr= ne->addr;
192       if (*bitaddr > 0x7f)
193         *celladdr= *bitaddr & 0xf8;
194       else
195         *celladdr= (*bitaddr >> 3) + 0x20;
196     }
197   // *bitaddr, *celladdr now OK
198   *cell= uc->get_bit//FIXME
199     (*bitaddr);
200   *bitmask= BIT_MASK(*bitaddr);
201   // making symbolic name
202   if (!symname)
203     return(DD_TRUE);
204   i= 0;
205   while (uc->bit_tbl()[i].name &&
206          (uc->bit_tbl()[i].addr != *bitaddr))
207     i++;
208   if (uc->bit_tbl()[i].name)
209     {
210       sym= strdup(uc->bit_tbl()[i].name);
211       *symname= sym;
212       return(DD_TRUE);
213     }
214   i= 0;
215   while (uc->sfr_tbl()[i].name &&
216          (uc->sfr_tbl()[i].addr != *celladdr))
217     i++;
218   if (uc->sfr_tbl()[i].name)
219     sym= strdup(uc->sfr_tbl()[i].name);
220   else
221     {
222       sym= (char *)malloc(3);
223       sprintf(sym, "%02x", *celladdr);
224     }
225   sym= (char *)realloc(sym, strlen(sym)+2);
226   strcat(sym, ".");
227   sprintf(bitnumstr, "%1d", *bitaddr & 0x07);
228   strcat(sym, bitnumstr);
229   *symname= sym;
230   return(DD_TRUE);
231 }*/
232
233
234 /*
235  * Processing escape sequencies in a string
236  */
237
238 char *
239 proc_escape(char *string, int *len)
240 {
241   char  spec_chars[]= "fnrtvab\"";
242   char  spec[]= "\f\n\r\t\v\a\b\"";
243   char  *s, *str, *p;
244
245   s  = string;
246   str= (char *)malloc(strlen(string)+1);
247   p  = str;
248   while (*s)
249     {
250       char *spec_c;
251
252       if (*s == '\\' &&
253           *(s+1))
254         {
255           s++;
256           if (*s == '0')
257             {
258               if (!isdigit(*(s+1)))
259                 {
260                   *p++= '\0';
261                   s++;
262                 }
263               else
264                 {
265                   char *octal, *chk, data;
266                   int i, j;
267                   i= strspn(s, "01234567");
268                   octal= (char *)malloc(i+1);
269                   j= 0;
270                   while (*s &&
271                          (j < i))
272                     octal[j++]= *s++;
273                   octal[j]= '\0';
274                   data= strtol(octal, &chk, 8);
275                   if (!chk || !(*chk))
276                     *p++= data;
277                 }
278             }
279           else
280             if ((spec_c= strchr(spec_chars, *s)) != NULL)
281               {
282                 *p++= spec[spec_c-spec_chars];
283                 s++;
284               }
285             else
286               *p++= *s++;
287         }
288       else
289         *p++= *s++;
290     }
291   *p= '\0';
292   *len= p-str;
293   return(str);
294 }
295
296
297
298 extern "C" int vasprintf(char **strp, const  char *format, va_list ap);
299 extern "C" int vsnprintf(char *str, size_t size,const char *format,va_list ap);
300
301 int
302 cmd_vfprintf(FILE *f, char *format, va_list ap)
303 {
304   int ret;
305   if (!f)
306     return(0);
307 #ifdef HAVE_VASPRINTF
308   char *msg= NULL;
309   vasprintf(&msg, format, ap);
310   ret= fprintf(f, "%s", msg);
311   free(msg);
312 #else
313 #  ifdef HAVE_VSNPRINTF
314   char msg[80*25];
315   vsnprintf(msg, 80*25, format, ap);
316   ret= fprintf(f, "%s", msg);
317 #  else
318 #    ifdef HAVE_VPRINTF
319   char msg[80*25];
320   vsprintf(msg, format, ap); /* Dangerous */
321   ret= fprintf(f, "%s", msg);
322 #    else
323 #      ifdef HAVE_DOPRNT
324   /* ??? */
325   /*strcpy(msg, "Unimplemented printf has called.\n");*/
326 #      else
327   /*strcpy(msg, "printf can not be implemented, upgrade your libc.\n");*/
328 #      endif
329 #    endif
330 #  endif
331 #endif
332   fflush(f);
333   return(ret);
334 }
335
336 int
337 cmd_fprintf(FILE *f, char *format, ...)
338 {
339   va_list ap;
340   va_start(ap, format);
341   int ret= cmd_vfprintf(f, format, ap);
342   va_end(ap);
343   return(ret);
344 }
345
346
347 /* End of cmd.src/cmdutil.cc */