sdcc-gas/sim/ucsim/utils.cc

595 lines
10 KiB
C++

/*
* Simulator of microcontrollers (utils.cc)
*
* Copyright (C) 1997,16 Drotos Daniel, Talker Bt.
*
* 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"
#if defined(HAVE_VASPRINTF) && !defined(_GNU_SOURCE)
/* define before including stdio.h to enable vasprintf() declaration */
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include "i_string.h"
// prj
#include "stypes.h"
#include "pobjcl.h"
#include "utils.h"
int
get_sub_opt(char **option, const char * const *tokens, char **valuep)
{
char *end, *equ;
int i;
if (!(end= strchr(*option, ',')))
end= *option + strlen(*option);
else
*end++= '\0';
if ((equ= strchr(*option, '=')))
{
*valuep= equ+1;
*equ= '\0';
}
else
*valuep= 0;
i= 0;
while (tokens[i] &&
strcmp(*option, tokens[i]))
i++;
if (!tokens[i])
*valuep= *option;
*option= end;
return tokens[i]?i:-1;
}
char *
get_id_string(struct id_element *ids, int id)
{
int i= 0;
while (ids[i].id_string &&
id != ids[i].id)
i++;
return(cchars(ids[i].id_string));
}
char *
get_id_string(struct id_element *ids, int id, char *def)
{
char *s= get_id_string(ids, id);
return(s?s:def);
}
int
get_string_id(struct id_element *ids, char *str)
{
int i= 0;
while (ids[i].id_string &&
strcmp(ids[i].id_string, str) != 0)
i++;
return(ids[i].id);
}
int
get_string_id(struct id_element *ids, char *str, int def)
{
int i= 0;
while (ids[i].id_string &&
strcmp(ids[i].id_string, str) != 0)
i++;
return(ids[i].id_string?ids[i].id:def);
}
char *
vformat_string(const char *format, va_list ap)
{
char *msg= NULL;
#ifdef HAVE_VASPRINTF
if (0 > vasprintf(&msg, format, ap))
msg = NULL;
return(msg);
#else
msg = (char*)malloc(80*25);
vsnprintf(msg, 80*25, format, ap);
#endif
return(msg);
}
char *
format_string(const char *format, ...)
{
va_list ap;
va_start(ap, format);
char *s= vformat_string(format, ap);
va_end(ap);
return(s);
}
void
print_char_octal(char c, FILE *f)
{
if (strchr("\a\b\f\n\r\t\v\"", c))
switch (c)
{
case '\a': fprintf(f, "\a"); break;
case '\b': fprintf(f, "\b"); break;
case '\f': fprintf(f, "\f"); break;
case '\n': fprintf(f, "\n"); break;
case '\r': fprintf(f, "\r"); break;
case '\t': fprintf(f, "\t"); break;
case '\v': fprintf(f, "\v"); break;
case '\"': fprintf(f, "\""); break;
}
else if (isprint(c))
fprintf(f, "%c", c);
else
fprintf(f, "\\%03o", (int)c);
}
const char *
object_name(class cl_base *o)
{
const char *name= 0;
if (o)
name= o->get_name();
if (name &&
*name)
return(name);
return(cchars("(unknown)"));
}
char *
case_string(enum letter_case lcase, char *str)
{
char *p= strdup(str);
char *s= p;
switch (lcase)
{
case case_upper:
while (p && *p) {
*p= toupper(*p);
p++;
}
break;
case case_lower:
while (p && *p) {
*p= tolower(*p);
p++;
}
break;
case case_case:
if (!p || *p == '\0')
break;
while (isspace(*p)) p++;
if (*p)
*p= toupper(*p);
break;
}
return(s);
}
chars
cbin(long data, int bits)
{
long mask= 1;
chars c= "";
mask= mask << ((bits >= 1)?(bits-1):0);
while (bits--)
{
c+= (data&mask)?'1':'0';
mask>>= 1;
}
return c;
}
/*char *
case_string(enum letter_case lcase, const char *str)
{
char *p= NIL;
if (!str ||
!*str)
return(NIL);
p= strdup(str);
return case_string(lcase, p);
}*/
double
dnow(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (double)tv.tv_sec + ((double)tv.tv_usec/1000000.0);
}
int
strispn(char *s, char c)
{
if (!s || !*s)
return 0;
char *p= strchr(s, c);
if (!p)
return -1;
return p-s;
}
/* Return true if "serach_in" string ends with string "what" */
bool
strend(char *search_in, char *what)
{
if (!search_in ||
!what ||
!*search_in ||
!*what)
return false;
char *start= strstr(search_in, what);
if (start == NULL)
return false;
if (start[strlen(what)] == '\0')
return true;
return false;
}
bool
valid_sym_name(char *s)
{
if (!s || !*s)
return false;
if (!isalpha(*s) &&
(*s != '_'))
return false;
char *p= s+1;
for (; *p; p++)
{
if (!isalnum(*p) &&
(*p != '_'))
return false;
}
return true;
}
bool
is_hex_file(class cl_f *f)
{
char *n;
if (!f)
return false;
n= f->get_file_name();
if (!n ||
!*n)
return false;
if (strend(n, cchars(".ihx")) ||
strend(n, cchars(".hex")) ||
strend(n, cchars(".ihex")))
return true;
return false;
}
bool
is_omf_file(class cl_f *f)
{
char *n;
if (!f)
return false;
n= f->get_file_name();
if (!n ||
!*n)
return false;
if (strend(n, cchars(".omf")))
return true;
return false;
}
bool
is_cdb_file(class cl_f *f)
{
char *n;
if (!f)
return false;
n= f->get_file_name();
if (!n ||
!*n)
return false;
if (strend(n, cchars(".cdb")))
return true;
return false;
}
/*
option_name=col_opt:col_opt
option_name=
prompt prompt_console command answer
dump_address dump_number dump_char
col_opt=
B bold
F faint
I italic
U underline
D double_underline
C crossedout
O overline
KL blink
col_opt=
black red green yellow blue magenta cyan white
bblack bred bgreen byellow bblue bmagenta bcyan bwhite
#RGB
*/
enum col_ctype_t
{
ct_none= 0,
ct_bold= 0x01,
ct_faint= 0x02,
ct_italic= 0x04,
ct_underl= 0x08,
ct_dunderl= 0x10,
ct_crossed= 0x20,
ct_overl= 0x40,
ct_blink= 0x80
};
chars
colopt2ansiseq(char *opt)
{
bool fg_rgb= false, bg_rgb= false;
bool fg_bright= false, bg_bright= false;
chars r= "";
int fg= -1, bg= -1;
int ctype= ct_none;
chars o;
if (!opt ||
!*opt)
return r;
o= opt;
char *s= strtok((char*)o, ":");
while (s)
{
if (strcmp(s, "black") == 0)
{
if (fg<0)
fg= 0;
else
bg= 0;
}
else if (strcmp(s, "bblack") == 0)
{
if (fg<0)
fg= 0, fg_bright= true;
else
bg= 0, bg_bright= true;
}
else if (strcmp(s, "red") == 0)
{
if (fg<0)
fg= 1;
else
bg= 1;
}
else if (strcmp(s, "bred") == 0)
{
if (fg<0)
fg= 1, fg_bright= true;
else
bg= 1, bg_bright= true;
}
else if (strcmp(s, "green") == 0)
{
if (fg<0)
fg= 2;
else
bg= 2;
}
else if (strcmp(s, "bgreen") == 0)
{
if (fg<0)
fg= 2, fg_bright= true;
else
bg= 2, bg_bright= true;
}
else if (strcmp(s, "yellow") == 0)
{
if (fg<0)
fg= 3;
else
bg= 3;
}
else if (strcmp(s, "byellow") == 0)
{
if (fg<0)
fg= 3, fg_bright= true;
else
bg= 3, bg_bright= true;
}
else if (strcmp(s, "blue") == 0)
{
if (fg<0)
fg= 4;
else
bg= 4;
}
else if (strcmp(s, "bblue") == 0)
{
if (fg<0)
fg= 4, fg_bright= true;
else
bg= 4, bg_bright= true;
}
else if (strcmp(s, "magenta") == 0)
{
if (fg<0)
fg= 5;
else
bg= 5;
}
else if (strcmp(s, "bmagenta") == 0)
{
if (fg<0)
fg= 5, fg_bright= true;
else
bg= 5, bg_bright= true;
}
else if (strcmp(s, "cyan") == 0)
{
if (fg<0)
fg= 6;
else
bg= 6;
}
else if (strcmp(s, "bcyan") == 0)
{
if (fg<0)
fg= 6, fg_bright= true;
else
bg= 6, bg_bright= true;
}
else if (strcmp(s, "white") == 0)
{
if (fg<0)
fg= 7;
else
bg= 7;
}
else if (strcmp(s, "bwhite") == 0)
{
if (fg<0)
fg= 7, fg_bright= true;
else
bg= 7, bg_bright= true;
}
else if (*s == '#')
{
int c= strtol(&s[1], NULL, 16);
if (fg<0)
fg= c, fg_rgb= true;
else
bg= c, bg_rgb= true;
}
else if (strspn(s, "bBfFiIuUdDcCoOkKlL") > 0)
{
int i;
for (i=0; s[i]; i++)
{
switch (toupper(s[i]))
{
case 'B': ctype|= ct_bold; break;
case 'F': ctype|= ct_faint; break;
case 'I': ctype|= ct_italic; break;
case 'U': ctype|= ct_underl; break;
case 'D': ctype|= ct_dunderl; break;
case 'C': ctype|= ct_crossed; break;
case 'O': ctype|= ct_overl; break;
case 'K': ctype|= ct_blink; break;
case 'L': ctype|= ct_blink; break;
}
}
}
s= strtok(NULL, ":");
}
/* set character rendering mode */
if (ctype != ct_none)
{
if (ctype & ct_bold) r.append("\033[1m");
if (ctype & ct_faint) r.append("\033[2m");
if (ctype & ct_italic) r.append("\033[3m");
if (ctype & ct_underl) r.append("\033[4m");
if (ctype & ct_dunderl) r.append("\033[21m");
if (ctype & ct_crossed) r.append("\033[9m");
if (ctype & ct_overl) r.append("\033[53m");
if (ctype & ct_blink) r.append("\033[5m");
}
/* Background color */
if (bg >= 0)
{
if (bg_rgb)
{
r.append("\033[48;2;%d;%d;%dm", (bg>>16)&0xff, (bg>>8)&0xff, bg&0xff);
}
else
{
int i= 40+bg;
if (bg_bright)
i= 100+bg;
r.append("\033[%dm", i);
}
}
/* Foreground color */
if (fg >= 0)
{
if (fg_rgb)
{
r.append("\033[38;2;%d;%d;%dm", (fg>>16)&0xff, (fg>>8)&0xff, fg&0xff);
}
else
{
int i= 30+fg;
if (fg_bright)
i= 90+fg;
r.append("\033[%dm", i);
}
}
return r;
}
/* End of utils.cc */