SCP: Add TIME_MSEC predefined variable to provide time to milliseconds

- Assure that Internal variables are referencable during expression evaluation
- Add DEVNAME.REGNAME format for referencing non unique registers in
  expression evaluation.
- Extend global register search to also search known internal device list
  registers
- Allow expression variable names to have _ as a character within in the name
This commit is contained in:
Mark Pizzolato 2018-05-24 01:46:24 -07:00
parent ed1a6f313e
commit 0daff9026d
2 changed files with 238 additions and 194 deletions

Binary file not shown.

432
scp.c
View file

@ -591,6 +591,7 @@ static const char *sim_do_ocptr[MAX_DO_NEST_LVL+1];
static const char *sim_do_label[MAX_DO_NEST_LVL+1]; static const char *sim_do_label[MAX_DO_NEST_LVL+1];
t_stat sim_last_cmd_stat; /* Command Status */ t_stat sim_last_cmd_stat; /* Command Status */
struct timespec cmd_time; /* */
static SCHTAB sim_stabr; /* Register search specifier */ static SCHTAB sim_stabr; /* Register search specifier */
static SCHTAB sim_staba; /* Memory search specifier */ static SCHTAB sim_staba; /* Memory search specifier */
@ -1455,8 +1456,8 @@ static const char simh_help[] =
" Built In variables %%DATE%%, %%TIME%%, %%DATETIME%%, %%LDATE%%, %%LTIME%%,\n" " Built In variables %%DATE%%, %%TIME%%, %%DATETIME%%, %%LDATE%%, %%LTIME%%,\n"
" %%CTIME%%, %%DATE_YYYY%%, %%DATE_YY%%, %%DATE_YC%%, %%DATE_MM%%, %%DATE_MMM%%,\n" " %%CTIME%%, %%DATE_YYYY%%, %%DATE_YY%%, %%DATE_YC%%, %%DATE_MM%%, %%DATE_MMM%%,\n"
" %%DATE_MONTH%%, %%DATE_DD%%, %%DATE_D%%, %%DATE_WYYYY%%, %%DATE_WW%%,\n" " %%DATE_MONTH%%, %%DATE_DD%%, %%DATE_D%%, %%DATE_WYYYY%%, %%DATE_WW%%,\n"
" %%TIME_HH%%, %%TIME_MM%%, %%TIME_SS%%, %%STATUS%%, %%TSTATUS%%, %%SIM_VERIFY%%,\n" " %%TIME_HH%%, %%TIME_MM%%, %%TIME_SS%%, %%TIME_MSEC%%, %%STATUS%%, %%TSTATUS%%,\n"
" %%SIM_QUIET%%, %%SIM_MESSAGE%% %%SIM_MESSAGE%%\n" " %%SIM_VERIFY%%, %%SIM_QUIET%%, %%SIM_MESSAGE%% %%SIM_MESSAGE%%\n"
" %%SIM_NAME%%, %%SIM_BIN_NAME%%, %%SIM_BIN_PATH%%m %%SIM_OSTYPE%%\n\n" " %%SIM_NAME%%, %%SIM_BIN_NAME%%, %%SIM_BIN_PATH%%m %%SIM_OSTYPE%%\n\n"
"+Token %%0 expands to the command file name.\n" "+Token %%0 expands to the command file name.\n"
"+Token %%n (n being a single digit) expands to the n'th argument\n" "+Token %%n (n being a single digit) expands to the n'th argument\n"
@ -1491,6 +1492,7 @@ static const char simh_help[] =
"++%%TIME_HH%% hh (00-23)\n" "++%%TIME_HH%% hh (00-23)\n"
"++%%TIME_MM%% mm (00-59)\n" "++%%TIME_MM%% mm (00-59)\n"
"++%%TIME_SS%% ss (00-59)\n" "++%%TIME_SS%% ss (00-59)\n"
"++%%TIME_MSEC%% msec (000-999)\n"
"++%%STATUS%% Status value from the last command executed\n" "++%%STATUS%% Status value from the last command executed\n"
"++%%TSTATUS%% The text form of the last status value\n" "++%%TSTATUS%% The text form of the last status value\n"
"++%%SIM_VERIFY%% The Verify/Verbose mode of the current Do command file\n" "++%%SIM_VERIFY%% The Verify/Verbose mode of the current Do command file\n"
@ -3537,6 +3539,185 @@ return stat | SCPE_NOMESSAGE; /* suppress message sinc
untouched. untouched.
*/ */
static const char *
_sim_get_env_special (const char *gbuf, char *rbuf, size_t rbuf_size)
{
const char *ap;
char tbuf[CBUFSIZE];
ap = getenv(gbuf); /* first try using the literal name */
if (!ap) {
get_glyph (gbuf, tbuf, 0); /* now try using the upcased name */
ap = getenv(tbuf);
}
if (ap) /* environment variable found? */
strlcpy (rbuf, ap, rbuf_size); /* Return the environment value */
else { /* otherwise, check for Special Names */
time_t now = (time_t)cmd_time.tv_sec;
struct tm *tmnow = localtime(&now);
/* ISO 8601 format date/time info */
if (!strcmp ("DATE", gbuf)) {
sprintf (rbuf, "%4d-%02d-%02d", tmnow->tm_year+1900, tmnow->tm_mon+1, tmnow->tm_mday);
ap = rbuf;
}
else if (!strcmp ("TIME", gbuf)) {
sprintf (rbuf, "%02d:%02d:%02d", tmnow->tm_hour, tmnow->tm_min, tmnow->tm_sec);
ap = rbuf;
}
else if (!strcmp ("DATETIME", gbuf)) {
sprintf (rbuf, "%04d-%02d-%02dT%02d:%02d:%02d", tmnow->tm_year+1900, tmnow->tm_mon+1, tmnow->tm_mday, tmnow->tm_hour, tmnow->tm_min, tmnow->tm_sec);
ap = rbuf;
}
/* Locale oriented formatted date/time info */
else if (!strcmp ("LDATE", gbuf)) {
strftime (rbuf, rbuf_size, "%x", tmnow);
ap = rbuf;
}
else if (!strcmp ("LTIME", gbuf)) {
#if defined(HAVE_C99_STRFTIME)
strftime (rbuf, rbuf_size, "%r", tmnow);
#else
strftime (rbuf, rbuf_size, "%p", tmnow);
if (rbuf[0])
strftime (rbuf, rbuf_size, "%I:%M:%S %p", tmnow);
else
strftime (rbuf, rbuf_size, "%H:%M:%S", tmnow);
#endif
ap = rbuf;
}
else if (!strcmp ("CTIME", gbuf)) {
#if defined(HAVE_C99_STRFTIME)
strftime (rbuf, rbuf_size, "%c", tmnow);
#else
strcpy (rbuf, ctime(&now));
rbuf[strlen (rbuf)-1] = '\0'; /* remove trailing \n */
#endif
ap = rbuf;
}
else if (!strcmp ("UTIME", gbuf)) {
sprintf (rbuf, "%" LL_FMT "d", (LL_TYPE)now);
ap = rbuf;
}
/* Separate Date/Time info */
else if (!strcmp ("DATE_YYYY", gbuf)) {/* Year (0000-9999) */
strftime (rbuf, sizeof(rbuf), "%Y", tmnow);
ap = rbuf;
}
else if (!strcmp ("DATE_YY", gbuf)) {/* Year (00-99) */
strftime (rbuf, sizeof(rbuf), "%y", tmnow);
ap = rbuf;
}
else if (!strcmp ("DATE_YC", gbuf)) {/* Century (year/100) */
sprintf (rbuf, "%d", (tmnow->tm_year + 1900)/100);
ap = rbuf;
}
else if ((!strcmp ("DATE_19XX_YY", gbuf)) || /* Year with same calendar */
(!strcmp ("DATE_19XX_YYYY", gbuf))) {
int year = tmnow->tm_year + 1900;
int days = year - 2001;
int leaps = days/4 - days/100 + days/400;
int lyear = ((year % 4) == 0) && (((year % 100) != 0) || ((year % 400) == 0));
int selector = ((days + leaps + 7) % 7) + lyear * 7;
static int years[] = {90, 91, 97, 98, 99, 94, 89,
96, 80, 92, 76, 88, 72, 84};
int cal_year = years[selector];
if (!strcmp ("DATE_19XX_YY", gbuf))
sprintf (rbuf, "%d", cal_year); /* 2 digit year */
else
sprintf (rbuf, "%d", cal_year + 1900); /* 4 digit year */
ap = rbuf;
}
else if (!strcmp ("DATE_MM", gbuf)) {/* Month number (01-12) */
strftime (rbuf, sizeof(rbuf), "%m", tmnow);
ap = rbuf;
}
else if (!strcmp ("DATE_MMM", gbuf)) {/* abbreviated Month name */
strftime (rbuf, sizeof(rbuf), "%b", tmnow);
ap = rbuf;
}
else if (!strcmp ("DATE_MONTH", gbuf)) {/* full Month name */
strftime (rbuf, sizeof(rbuf), "%B", tmnow);
ap = rbuf;
}
else if (!strcmp ("DATE_DD", gbuf)) {/* Day of Month (01-31) */
strftime (rbuf, sizeof(rbuf), "%d", tmnow);
ap = rbuf;
}
else if (!strcmp ("DATE_D", gbuf)) { /* ISO 8601 weekday number (1-7) */
sprintf (rbuf, "%d", (tmnow->tm_wday ? tmnow->tm_wday : 7));
ap = rbuf;
}
else if ((!strcmp ("DATE_WW", gbuf)) || /* ISO 8601 week number (01-53) */
(!strcmp ("DATE_WYYYY", gbuf))) {/* ISO 8601 week year number (0000-9999) */
int iso_yr = tmnow->tm_year + 1900;
int iso_wk = (tmnow->tm_yday + 11 - (tmnow->tm_wday ? tmnow->tm_wday : 7))/7;;
if (iso_wk == 0) {
iso_yr = iso_yr - 1;
tmnow->tm_yday += 365 + (((iso_yr % 4) == 0) ? 1 : 0); /* Adjust for Leap Year (Correct thru 2099) */
iso_wk = (tmnow->tm_yday + 11 - (tmnow->tm_wday ? tmnow->tm_wday : 7))/7;
}
else
if ((iso_wk == 53) && (((31 - tmnow->tm_mday) + tmnow->tm_wday) < 4)) {
++iso_yr;
iso_wk = 1;
}
if (!strcmp ("DATE_WW", gbuf))
sprintf (rbuf, "%02d", iso_wk);
else
sprintf (rbuf, "%04d", iso_yr);
ap = rbuf;
}
else if (!strcmp ("DATE_JJJ", gbuf)) {/* day of year (001-366) */
strftime (rbuf, sizeof(rbuf), "%j", tmnow);
ap = rbuf;
}
else if (!strcmp ("TIME_HH", gbuf)) {/* Hour of day (00-23) */
strftime (rbuf, sizeof(rbuf), "%H", tmnow);
ap = rbuf;
}
else if (!strcmp ("TIME_MM", gbuf)) {/* Minute of hour (00-59) */
strftime (rbuf, sizeof(rbuf), "%M", tmnow);
ap = rbuf;
}
else if (!strcmp ("TIME_SS", gbuf)) {/* Second of minute (00-59) */
strftime (rbuf, sizeof(rbuf), "%S", tmnow);
ap = rbuf;
}
else if (!strcmp ("TIME_MSEC", gbuf)) {/* Milliseconds of Second (000-999) */
sprintf (rbuf, "%03d", (int)(cmd_time.tv_nsec / 1000000));
ap = rbuf;
}
else if (!strcmp ("STATUS", gbuf)) {
sprintf (rbuf, "%08X", sim_last_cmd_stat);
ap = rbuf;
}
else if (!strcmp ("TSTATUS", gbuf)) {
sprintf (rbuf, "%s", sim_error_text (sim_last_cmd_stat));
ap = rbuf;
}
else if (!strcmp ("SIM_VERIFY", gbuf)) {
sprintf (rbuf, "%s", sim_do_echo ? "-V" : "");
ap = rbuf;
}
else if (!strcmp ("SIM_VERBOSE", gbuf)) {
sprintf (rbuf, "%s", sim_do_echo ? "-V" : "");
ap = rbuf;
}
else if (!strcmp ("SIM_QUIET", gbuf)) {
sprintf (rbuf, "%s", sim_quiet ? "-Q" : "");
ap = rbuf;
}
else if (!strcmp ("SIM_MESSAGE", gbuf)) {
sprintf (rbuf, "%s", sim_show_message ? "" : "-Q");
ap = rbuf;
}
}
return ap;
}
void sim_sub_args (char *instr, size_t instr_size, char *do_arg[]) void sim_sub_args (char *instr, size_t instr_size, char *do_arg[])
{ {
char gbuf[CBUFSIZE]; char gbuf[CBUFSIZE];
@ -3546,11 +3727,8 @@ char rbuf[CBUFSIZE];
int i; int i;
size_t instr_off = 0; size_t instr_off = 0;
size_t outstr_off = 0; size_t outstr_off = 0;
time_t now;
struct tm *tmnow;
time(&now); clock_gettime(CLOCK_REALTIME, &cmd_time);
tmnow = localtime(&now);
tmpbuf = (char *)malloc(instr_size); tmpbuf = (char *)malloc(instr_size);
op = tmpbuf; op = tmpbuf;
oend = tmpbuf + instr_size - 2; oend = tmpbuf + instr_size - 2;
@ -3625,172 +3803,12 @@ for (; *ip && (op < oend); ) {
break; break;
ip = ip + 2; ip = ip + 2;
} }
else { /* environment variable */ else { /* check environment variable or special variables */
ap = NULL; get_glyph_nc (ip+1, gbuf, '%'); /* get the literal name */
get_glyph_nc (ip+1, gbuf, '%'); /* first try using the literal name */ ap = _sim_get_env_special (gbuf, rbuf, sizeof (rbuf));
ap = getenv(gbuf);
if (!ap) {
get_glyph (ip+1, gbuf, '%'); /* now try using the upcased name */
ap = getenv(gbuf);
}
ip += 1 + strlen (gbuf); ip += 1 + strlen (gbuf);
if (*ip == '%') ++ip; if (*ip == '%')
if (!ap) { ++ip;
/* ISO 8601 format date/time info */
if (!strcmp ("DATE", gbuf)) {
sprintf (rbuf, "%4d-%02d-%02d", tmnow->tm_year+1900, tmnow->tm_mon+1, tmnow->tm_mday);
ap = rbuf;
}
else if (!strcmp ("TIME", gbuf)) {
sprintf (rbuf, "%02d:%02d:%02d", tmnow->tm_hour, tmnow->tm_min, tmnow->tm_sec);
ap = rbuf;
}
else if (!strcmp ("DATETIME", gbuf)) {
sprintf (rbuf, "%04d-%02d-%02dT%02d:%02d:%02d", tmnow->tm_year+1900, tmnow->tm_mon+1, tmnow->tm_mday, tmnow->tm_hour, tmnow->tm_min, tmnow->tm_sec);
ap = rbuf;
}
/* Locale oriented formatted date/time info */
else if (!strcmp ("LDATE", gbuf)) {
strftime (rbuf, sizeof(rbuf), "%x", tmnow);
ap = rbuf;
}
else if (!strcmp ("LTIME", gbuf)) {
#if defined(HAVE_C99_STRFTIME)
strftime (rbuf, sizeof(rbuf), "%r", tmnow);
#else
strftime (rbuf, sizeof(rbuf), "%p", tmnow);
if (rbuf[0])
strftime (rbuf, sizeof(rbuf), "%I:%M:%S %p", tmnow);
else
strftime (rbuf, sizeof(rbuf), "%H:%M:%S", tmnow);
#endif
ap = rbuf;
}
else if (!strcmp ("CTIME", gbuf)) {
#if defined(HAVE_C99_STRFTIME)
strftime (rbuf, sizeof(rbuf), "%c", tmnow);
#else
strcpy (rbuf, ctime(&now));
rbuf[strlen (rbuf)-1] = '\0'; /* remove trailing \n */
#endif
ap = rbuf;
}
else if (!strcmp ("UTIME", gbuf)) {
sprintf (rbuf, "%" LL_FMT "d", (LL_TYPE)now);
ap = rbuf;
}
/* Separate Date/Time info */
else if (!strcmp ("DATE_YYYY", gbuf)) {/* Year (0000-9999) */
strftime (rbuf, sizeof(rbuf), "%Y", tmnow);
ap = rbuf;
}
else if (!strcmp ("DATE_YY", gbuf)) {/* Year (00-99) */
strftime (rbuf, sizeof(rbuf), "%y", tmnow);
ap = rbuf;
}
else if (!strcmp ("DATE_YC", gbuf)) {/* Century (year/100) */
sprintf (rbuf, "%d", (tmnow->tm_year + 1900)/100);
ap = rbuf;
}
else if ((!strcmp ("DATE_19XX_YY", gbuf)) || /* Year with same calendar */
(!strcmp ("DATE_19XX_YYYY", gbuf))) {
int year = tmnow->tm_year + 1900;
int days = year - 2001;
int leaps = days/4 - days/100 + days/400;
int lyear = ((year % 4) == 0) && (((year % 100) != 0) || ((year % 400) == 0));
int selector = ((days + leaps + 7) % 7) + lyear * 7;
static int years[] = {90, 91, 97, 98, 99, 94, 89,
96, 80, 92, 76, 88, 72, 84};
int cal_year = years[selector];
if (!strcmp ("DATE_19XX_YY", gbuf))
sprintf (rbuf, "%d", cal_year); /* 2 digit year */
else
sprintf (rbuf, "%d", cal_year + 1900); /* 4 digit year */
ap = rbuf;
}
else if (!strcmp ("DATE_MM", gbuf)) {/* Month number (01-12) */
strftime (rbuf, sizeof(rbuf), "%m", tmnow);
ap = rbuf;
}
else if (!strcmp ("DATE_MMM", gbuf)) {/* abbreviated Month name */
strftime (rbuf, sizeof(rbuf), "%b", tmnow);
ap = rbuf;
}
else if (!strcmp ("DATE_MONTH", gbuf)) {/* full Month name */
strftime (rbuf, sizeof(rbuf), "%B", tmnow);
ap = rbuf;
}
else if (!strcmp ("DATE_DD", gbuf)) {/* Day of Month (01-31) */
strftime (rbuf, sizeof(rbuf), "%d", tmnow);
ap = rbuf;
}
else if (!strcmp ("DATE_D", gbuf)) { /* ISO 8601 weekday number (1-7) */
sprintf (rbuf, "%d", (tmnow->tm_wday ? tmnow->tm_wday : 7));
ap = rbuf;
}
else if ((!strcmp ("DATE_WW", gbuf)) || /* ISO 8601 week number (01-53) */
(!strcmp ("DATE_WYYYY", gbuf))) {/* ISO 8601 week year number (0000-9999) */
int iso_yr = tmnow->tm_year + 1900;
int iso_wk = (tmnow->tm_yday + 11 - (tmnow->tm_wday ? tmnow->tm_wday : 7))/7;;
if (iso_wk == 0) {
iso_yr = iso_yr - 1;
tmnow->tm_yday += 365 + (((iso_yr % 4) == 0) ? 1 : 0); /* Adjust for Leap Year (Correct thru 2099) */
iso_wk = (tmnow->tm_yday + 11 - (tmnow->tm_wday ? tmnow->tm_wday : 7))/7;
}
else
if ((iso_wk == 53) && (((31 - tmnow->tm_mday) + tmnow->tm_wday) < 4)) {
++iso_yr;
iso_wk = 1;
}
if (!strcmp ("DATE_WW", gbuf))
sprintf (rbuf, "%02d", iso_wk);
else
sprintf (rbuf, "%04d", iso_yr);
ap = rbuf;
}
else if (!strcmp ("DATE_JJJ", gbuf)) {/* day of year (001-366) */
strftime (rbuf, sizeof(rbuf), "%j", tmnow);
ap = rbuf;
}
else if (!strcmp ("TIME_HH", gbuf)) {/* Hour of day (00-23) */
strftime (rbuf, sizeof(rbuf), "%H", tmnow);
ap = rbuf;
}
else if (!strcmp ("TIME_MM", gbuf)) {/* Minute of hour (00-59) */
strftime (rbuf, sizeof(rbuf), "%M", tmnow);
ap = rbuf;
}
else if (!strcmp ("TIME_SS", gbuf)) {/* Second of minute (00-59) */
strftime (rbuf, sizeof(rbuf), "%S", tmnow);
ap = rbuf;
}
else if (!strcmp ("STATUS", gbuf)) {
sprintf (rbuf, "%08X", sim_last_cmd_stat);
ap = rbuf;
}
else if (!strcmp ("TSTATUS", gbuf)) {
sprintf (rbuf, "%s", sim_error_text (sim_last_cmd_stat));
ap = rbuf;
}
else if (!strcmp ("SIM_VERIFY", gbuf)) {
sprintf (rbuf, "%s", sim_do_echo ? "-V" : "");
ap = rbuf;
}
else if (!strcmp ("SIM_VERBOSE", gbuf)) {
sprintf (rbuf, "%s", sim_do_echo ? "-V" : "");
ap = rbuf;
}
else if (!strcmp ("SIM_QUIET", gbuf)) {
sprintf (rbuf, "%s", sim_quiet ? "-Q" : "");
ap = rbuf;
}
else if (!strcmp ("SIM_MESSAGE", gbuf)) {
sprintf (rbuf, "%s", sim_show_message ? "" : "-Q");
ap = rbuf;
}
}
} }
if (ap) { /* non-null arg? */ if (ap) { /* non-null arg? */
while (*ap && (op < oend)) { /* copy the argument */ while (*ap && (op < oend)) { /* copy the argument */
@ -9368,32 +9386,34 @@ return (dptr->flags & DEV_DIS? TRUE: FALSE);
REG *find_reg_glob_reason (CONST char *cptr, CONST char **optr, DEVICE **gdptr, t_stat *stat) REG *find_reg_glob_reason (CONST char *cptr, CONST char **optr, DEVICE **gdptr, t_stat *stat)
{ {
int32 i; int32 i, j;
DEVICE *dptr; DEVICE *dptr, **devs, **dptrptr[] = {sim_devices, sim_internal_devices, NULL};
REG *rptr, *srptr = NULL; REG *rptr, *srptr = NULL;
if (stat) if (stat)
*stat = SCPE_OK; *stat = SCPE_OK;
*gdptr = NULL; *gdptr = NULL;
for (i = 0; (dptr = sim_devices[i]) != 0; i++) { /* all dev */ for (j = 0; (devs = dptrptr[j]) != NULL; j++) {
if (dptr->flags & DEV_DIS) /* skip disabled */ for (i = 0; (dptr = devs[i]) != NULL; i++) { /* all dev */
continue; if (dptr->flags & DEV_DIS) /* skip disabled */
if ((rptr = find_reg (cptr, optr, dptr))) { /* found? */ continue;
if (srptr) { /* ambig? err */ if ((rptr = find_reg (cptr, optr, dptr))) { /* found? */
if (stat) { if (srptr) { /* ambig? err */
if (sim_show_message) { if (stat) {
if (*stat == SCPE_OK) if (sim_show_message) {
sim_printf ("Ambiguous register. %s appears in devices %s and %s", cptr, (*gdptr)->name, dptr->name); if (*stat == SCPE_OK)
else sim_printf ("Ambiguous register. %s appears in devices %s and %s", cptr, (*gdptr)->name, dptr->name);
sim_printf (" and %s", dptr->name); else
sim_printf (" and %s", dptr->name);
}
*stat = SCPE_AMBREG|SCPE_NOMESSAGE;
} }
*stat = SCPE_AMBREG|SCPE_NOMESSAGE; else
return NULL;
} }
else srptr = rptr; /* save reg */
return NULL; *gdptr = dptr; /* save unit */
} }
srptr = rptr; /* save reg */
*gdptr = dptr; /* save unit */
} }
} }
if (stat && (*stat != SCPE_OK)) { if (stat && (*stat != SCPE_OK)) {
@ -13609,7 +13629,7 @@ static const char BinaryDigits[] = "01";
while (isspace (*cptr)) while (isspace (*cptr))
++cptr; ++cptr;
if (isalpha (*cptr)) { if (isalpha (*cptr)) {
while (isalnum (*cptr)) while (isalnum (*cptr) || (*cptr == '.') || (*cptr == '_'))
*buf++ = *cptr++; *buf++ = *cptr++;
*buf = '\0'; *buf = '\0';
} }
@ -13784,9 +13804,26 @@ return cptr; /* return any unprocessed input */
static t_bool _value_of (const char *data, t_svalue *svalue, char *string, size_t string_size) static t_bool _value_of (const char *data, t_svalue *svalue, char *string, size_t string_size)
{ {
CONST char *gptr; CONST char *gptr;
if (isalpha (*data)) {
REG *rptr = find_reg (data, &gptr, sim_dfdev);
if (isalpha (*data)) {
REG *rptr;
DEVICE *dptr = sim_dfdev;
const char *dot;
dot = strchr (data, '.');
if (dot) {
char devnam[CBUFSIZE];
memcpy (devnam, data, dot - data);
devnam[dot - data] = '\0';
if (find_dev (devnam)) {
dptr = find_dev (devnam);
data = dot + 1;
rptr = find_reg (data, &gptr, dptr);
}
}
else
rptr = find_reg_glob (data, &gptr, &dptr);
if (rptr) { if (rptr) {
*svalue = (t_svalue)get_rval (rptr, 0); *svalue = (t_svalue)get_rval (rptr, 0);
sprint_val (string + 1, *svalue, 10, string_size - 2, PV_LEFTSIGN); sprint_val (string + 1, *svalue, 10, string_size - 2, PV_LEFTSIGN);
@ -13794,8 +13831,15 @@ if (isalpha (*data)) {
strlcpy (&string[strlen (string)], "\"", string_size - strlen (string)); strlcpy (&string[strlen (string)], "\"", string_size - strlen (string));
return TRUE; return TRUE;
} }
gptr = getenv (data); gptr = _sim_get_env_special (data, string + 1, string_size - 2);
data = (gptr ? gptr : ""); if (gptr) {
*svalue = strtotsv(string + 1, &gptr, 0);
*string = '"';
strlcpy (&string[strlen (string)], "\"", string_size - strlen (string));
return (*gptr == '\0');
}
else
data = "";
} }
*svalue = strtotsv(data, &gptr, 0); *svalue = strtotsv(data, &gptr, 0);
snprintf (string, string_size - 1, "\"%s\"", data); snprintf (string, string_size - 1, "\"%s\"", data);