[ucsim] Update email and file info, fix stm8 flash controller
[sdcc.git] / sdcc / sim / ucsim / src / core / utils.src / utils.cc
blobc9a1abd0b6af7fbb98cf345217520965499c1e09
1 /*
2 * Simulator of microcontrollers (utils.cc)
4 * Copyright (C) 1997 Drotos Daniel
5 *
6 * To contact author send email to dr.dkdb@gmail.com
8 */
10 /* This file is part of microcontroller simulator: ucsim.
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.
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.
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@*/
28 #include "ddconfig.h"
30 #if defined(HAVE_VASPRINTF) && !defined(_GNU_SOURCE)
31 /* define before including stdio.h to enable vasprintf() declaration */
32 #define _GNU_SOURCE
33 #endif
34 #include <stdio.h>
35 #include <ctype.h>
36 #include <stdarg.h>
37 #include <stdlib.h>
38 //#include <unistd.h>
39 #include <sys/time.h>
40 #include <time.h>
41 #include <string.h>
43 // prj
44 #include "stypes.h"
45 //#include "pobjcl.h"
47 #include "globals.h"
48 #include "utils.h"
51 int
52 get_sub_opt(char **option, const char * const *tokens, char **valuep)
54 char *end, *equ;
55 int i;
57 if (!(end= strchr(*option, ',')))
58 end= *option + strlen(*option);
59 else
60 *end++= '\0';
61 if ((equ= strchr(*option, '=')))
63 *valuep= equ+1;
64 *equ= '\0';
66 else
67 *valuep= 0;
68 i= 0;
69 while (tokens[i] &&
70 strcmp(*option, tokens[i]))
71 i++;
72 if (!tokens[i])
73 *valuep= *option;
74 *option= end;
75 return tokens[i]?i:-1;
79 const char *
80 get_id_string(struct id_element *ids, int id)
82 int i= 0;
84 while (ids[i].id_string &&
85 id != ids[i].id)
86 i++;
87 return(ids[i].id_string);
90 const char *
91 get_id_string(struct id_element *ids, int id, const char *def)
93 const char *s= get_id_string(ids, id);
95 return(s?s:def);
98 int
99 get_string_id(struct id_element *ids, char *str)
101 int i= 0;
103 while (ids[i].id_string &&
104 strcmp(ids[i].id_string, str) != 0)
105 i++;
106 return(ids[i].id);
110 get_string_id(struct id_element *ids, char *str, int def)
112 int i= 0;
114 while (ids[i].id_string &&
115 strcmp(ids[i].id_string, str) != 0)
116 i++;
117 return(ids[i].id_string?ids[i].id:def);
121 char *
122 vformat_string(const char *format, va_list ap)
124 char *msg= NULL;
125 #ifdef HAVE_VASPRINTF
126 if (0 > vasprintf(&msg, format, ap))
127 msg = NULL;
128 return(msg);
129 #else
130 #ifdef HAVE_VSNPRINTF
131 msg = (char*)malloc(80*25);
132 vsnprintf(msg, 80*25, format, ap);
133 #else
134 msg= (char*)malloc(80*25);
135 vsprintf(msg, format, ap);
136 #endif
137 #endif
138 return(msg);
141 char *
142 format_string(const char *format, ...)
144 va_list ap;
146 va_start(ap, format);
147 char *s= vformat_string(format, ap);
148 va_end(ap);
149 return(s);
153 void
154 print_char_octal(char c, FILE *f)
156 if (strchr("\a\b\f\n\r\t\v\"", c))
157 switch (c)
159 case '\a': fprintf(f, "\a"); break;
160 case '\b': fprintf(f, "\b"); break;
161 case '\f': fprintf(f, "\f"); break;
162 case '\n': fprintf(f, "\n"); break;
163 case '\r': fprintf(f, "\r"); break;
164 case '\t': fprintf(f, "\t"); break;
165 case '\v': fprintf(f, "\v"); break;
166 case '\"': fprintf(f, "\""); break;
168 else if (isprint(c))
169 fprintf(f, "%c", c);
170 else
171 fprintf(f, "\\%03o", (int)c);
175 const char *
176 object_name(class cl_base *o)
178 const char *name= 0;
180 if (o)
181 name= o->get_name();
182 if (name &&
183 *name)
184 return(name);
185 return("(unknown)");
189 char *
190 case_string(enum letter_case lcase, const char *str)
192 char *p= strdup(str);
193 char *s= p;
195 switch (lcase)
197 case case_upper:
198 while (p && *p) {
199 *p= toupper(*p);
200 p++;
202 break;
203 case case_lower:
204 while (p && *p) {
205 *p= tolower(*p);
206 p++;
208 break;
209 case case_case:
210 if (!p || *p == '\0')
211 break;
212 while (isspace(*p)) p++;
213 if (*p)
214 *p= toupper(*p);
215 break;
217 return(s);
220 chars
221 cbin(long data, int bits)
223 long mask= 1;
224 chars c= "";
226 mask= mask << ((bits >= 1)?(bits-1):0);
227 while (bits--)
229 c+= (data&mask)?'1':'0';
230 mask>>= 1;
232 return c;
236 strispn(char *s, char c)
238 if (!s || !*s)
239 return 0;
240 char *p= strchr(s, c);
241 if (!p)
242 return -1;
243 return p-s;
246 /* Return true if "serach_in" string ends with string "what" */
248 bool
249 strend(const char *search_in, const char *what)
251 if (!search_in ||
252 !what ||
253 !*search_in ||
254 !*what)
255 return false;
256 const char *start= strstr(search_in, what);
257 if (start == NULL)
258 return false;
259 if (start[strlen(what)] == '\0')
260 return true;
261 return false;
264 bool
265 valid_sym_name(char *s)
267 if (!s || !*s)
268 return false;
269 if (!isalpha(*s) &&
270 (*s != '_'))
271 return false;
272 char *p= s+1;
273 for (; *p; p++)
275 if (!isalnum(*p) &&
276 (*p != '_'))
277 return false;
279 return true;
283 bool
284 filename_has_ext(class cl_f *f, const char *ext)
286 const char *n;
287 if (!f)
288 return false;
289 n= f->get_file_name();
290 if (!n ||
291 !*n)
292 return false;
294 if (strend(n, ext))
295 return true;
297 return false;
300 bool
301 is_hex_file(class cl_f *f)
303 const char *n;
304 if (!f)
305 return false;
306 n= f->get_file_name();
307 if (!n ||
308 !*n)
309 return false;
311 if (strend(n, ".ihx") ||
312 strend(n, ".hex") ||
313 strend(n, ".ihex"))
314 return true;
316 return false;
319 bool
320 is_asc_file(class cl_f *f)
322 return filename_has_ext(f, ".asc");
325 bool
326 is_p2h_file(class cl_f *f)
328 return filename_has_ext(f, ".p2h");
331 bool
332 is_omf_file(class cl_f *f)
334 return filename_has_ext(f, ".omf");
337 bool
338 is_cdb_file(class cl_f *f)
340 return filename_has_ext(f, ".cdb");
343 bool
344 is_s19_file(class cl_f *f)
346 return filename_has_ext(f, ".s19");
349 bool
350 is_map_file(class cl_f *f)
352 return filename_has_ext(f, ".map");
356 option_name=col_opt:col_opt
358 option_name=
359 prompt prompt_console command answer
360 dump_address dump_label dump_number dump_char
362 col_opt=
363 B bold
364 F faint
365 I italic
366 U underline
367 D double_underline
368 C crossedout
369 O overline
370 KL blink
372 col_opt=
373 black red green yellow blue magenta cyan white
374 bblack bred bgreen byellow bblue bmagenta bcyan bwhite
375 #RGB
379 enum col_ctype_t
381 ct_none= 0,
382 ct_bold= 0x01,
383 ct_faint= 0x02,
384 ct_italic= 0x04,
385 ct_underl= 0x08,
386 ct_dunderl= 0x10,
387 ct_crossed= 0x20,
388 ct_overl= 0x40,
389 ct_blink= 0x80
392 chars
393 colopt2ansiseq(char *opt)
395 bool fg_rgb= false, bg_rgb= false;
396 bool fg_bright= false, bg_bright= false;
397 chars r= "", full= opt, tok= "";
398 int fg= -1, bg= -1;
399 int ctype= ct_none;
400 class cl_option *o= application->options->get_option("color_bg");
401 char *bgcolor;
402 if (o) o->get_value(&bgcolor);
404 if (!opt ||
405 !*opt)
406 return r;
407 tok.start_parse();
408 tok= full.token(":");
409 while (tok.nempty())
411 const char *s= tok.c_str();
412 if (tok=="bg")
413 tok= bgcolor;
414 if (tok=="black")
416 if (fg<0)
417 fg= 0;
418 else
419 bg= 0;
421 else if (tok=="bblack")
423 if (fg<0)
424 fg= 0, fg_bright= true;
425 else
426 bg= 0, bg_bright= true;
428 else if (tok=="red")
430 if (fg<0)
431 fg= 1;
432 else
433 bg= 1;
435 else if (tok=="bred")
437 if (fg<0)
438 fg= 1, fg_bright= true;
439 else
440 bg= 1, bg_bright= true;
442 else if (tok=="green")
444 if (fg<0)
445 fg= 2;
446 else
447 bg= 2;
449 else if (tok=="bgreen")
451 if (fg<0)
452 fg= 2, fg_bright= true;
453 else
454 bg= 2, bg_bright= true;
456 else if (tok=="yellow")
458 if (fg<0)
459 fg= 3;
460 else
461 bg= 3;
463 else if (tok=="byellow")
465 if (fg<0)
466 fg= 3, fg_bright= true;
467 else
468 bg= 3, bg_bright= true;
470 else if (tok=="blue")
472 if (fg<0)
473 fg= 4;
474 else
475 bg= 4;
477 else if (tok=="bblue")
479 if (fg<0)
480 fg= 4, fg_bright= true;
481 else
482 bg= 4, bg_bright= true;
484 else if (tok=="magenta")
486 if (fg<0)
487 fg= 5;
488 else
489 bg= 5;
491 else if (tok=="bmagenta")
493 if (fg<0)
494 fg= 5, fg_bright= true;
495 else
496 bg= 5, bg_bright= true;
498 else if (tok=="cyan")
500 if (fg<0)
501 fg= 6;
502 else
503 bg= 6;
505 else if (tok=="bcyan")
507 if (fg<0)
508 fg= 6, fg_bright= true;
509 else
510 bg= 6, bg_bright= true;
512 else if (tok=="white")
514 if (fg<0)
515 fg= 7;
516 else
517 bg= 7;
519 else if (tok=="bwhite")
521 if (fg<0)
522 fg= 7, fg_bright= true;
523 else
524 bg= 7, bg_bright= true;
526 else if (*s == '#')
528 int c= strtol(&s[1], NULL, 16);
529 if (fg<0)
530 fg= c, fg_rgb= true;
531 else
532 bg= c, bg_rgb= true;
534 else
536 int i;
537 if (strcspn(s, "bBfFiIuUdDcCoOkKlL") == 0)
538 for (i=0; s[i]; i++)
540 switch (toupper(s[i]))
542 case 'B': ctype|= ct_bold; break;
543 case 'F': ctype|= ct_faint; break;
544 case 'I': ctype|= ct_italic; break;
545 case 'U': ctype|= ct_underl; break;
546 case 'D': ctype|= ct_dunderl; break;
547 case 'C': ctype|= ct_crossed; break;
548 case 'O': ctype|= ct_overl; break;
549 case 'K': ctype|= ct_blink; break;
550 case 'L': ctype|= ct_blink; break;
554 tok= full.token(":");
557 /* set character rendering mode */
558 if (ctype != ct_none)
560 if (ctype & ct_bold) r.append("\033[1m");
561 if (ctype & ct_faint) r.append("\033[2m");
562 if (ctype & ct_italic) r.append("\033[3m");
563 if (ctype & ct_underl) r.append("\033[4m");
564 if (ctype & ct_dunderl) r.append("\033[21m");
565 if (ctype & ct_crossed) r.append("\033[9m");
566 if (ctype & ct_overl) r.append("\033[53m");
567 if (ctype & ct_blink) r.append("\033[5m");
570 /* Background color */
571 if (bg >= 0)
573 if (bg_rgb)
575 r.appendf("\033[48;2;%d;%d;%dm", (bg>>16)&0xff, (bg>>8)&0xff, bg&0xff);
577 else
579 int i= 40+bg;
580 if (bg_bright)
581 i= 100+bg;
582 r.appendf("\033[%dm", i);
586 /* Foreground color */
587 if (fg >= 0)
589 if (fg_rgb)
591 r.appendf("\033[38;2;%d;%d;%dm", (fg>>16)&0xff, (fg>>8)&0xff, fg&0xff);
593 else
595 int i= 30+fg;
596 if (fg_bright)
597 i= 90+fg;
598 r.appendf("\033[%dm", i);
602 return r;
605 double
606 strtoscale(const char *scale, const char **units)
608 double d = 1.0;
609 const char *u;
611 if (!units)
612 units = &u;
614 *units = &scale[0];
616 if (scale[0])
618 *units = &scale[1];
619 switch (scale[0])
621 case 'f':
622 d = 1 / 1000000000000000.0;
623 break;
624 case 'p':
625 d = 1 / 1000000000000.0;
626 break;
627 case 'n':
628 d = 1 / 1000000000.0;
629 break;
630 case 'u':
631 d = 1 / 1000000.0;
632 break;
633 case 'm':
634 d = 1 / 1000.0;
635 break;
636 default:
637 if (!strncmp(scale, "µ", sizeof("µ") - 1))
639 d = 1 / 1000000.0;
640 *units = &scale[sizeof("µ")];
642 else
644 if (scale[1] != 'i')
646 switch (scale[0])
648 case 'k':
649 d = 1000.0;
650 break;
651 case 'M':
652 d = 1000000.0;
653 break;
654 case 'G':
655 d = 1000000000.0;
656 break;
657 case 'T':
658 d = 1000000000000.0;
659 break;
660 case 'P':
661 d = 1000000000000000.0;
662 break;
663 default:
664 *units = &scale[0];
665 break;
668 else
670 *units = &scale[2];
671 switch (scale[0])
673 case 'k':
674 d = 1024.0;
675 break;
676 case 'M':
677 d = 1024.0 * 1024.0;
678 break;
679 case 'G':
680 d = 1024.0 * 1024.0 * 1024.0;
681 break;
682 case 'T':
683 d = 1024.0 * 1024.0 * 1024.0 * 1024.0;
684 break;
685 case 'P':
686 d = 1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0;
687 break;
688 default:
689 *units = &scale[0];
690 break;
694 break;
698 return d;
702 /* Custom random number generator */
704 #define PHI 0x9e3779b9
706 static u32_t Q[4096], c = 362436;
708 void
709 srnd(unsigned int seed)
711 int i;
713 Q[0] = seed;
714 Q[1] = seed + PHI;
715 Q[2] = seed + PHI + PHI;
717 for (i = 3; i < 4096; i++)
718 Q[i] = Q[i - 3] ^ Q[i - 2] ^ PHI ^ i;
721 unsigned int
722 urnd(void)
724 u64_t t, a = 18782LL;
725 static u32_t i = 4095;
726 u32_t x, r = 0xfffffffe;
727 i = (i + 1) & 4095;
728 t = a * Q[i] + c;
729 c = (t >> 32);
730 x = t + c;
731 if (x < c) {
732 x++;
733 c++;
735 return (Q[i] = r - x);
738 u8_t
739 urnd8()
741 return urnd();
744 u16_t
745 urnd16()
747 return urnd();
750 u32_t
751 urnd32()
753 return urnd();
757 /* End of utils.src/utils.cc */