scanf support for real values.
This commit is contained in:
parent
54c7ef72cb
commit
2c7e96caec
|
|
@ -17,12 +17,13 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: sys_display.c,v 1.71 2004/10/04 01:10:58 steve Exp $"
|
||||
#ident "$Id: sys_display.c,v 1.72 2006/08/12 03:38:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_config.h"
|
||||
|
||||
# include "vpi_user.h"
|
||||
# include "sys_priv.h"
|
||||
# include <assert.h>
|
||||
# include <string.h>
|
||||
# include <ctype.h>
|
||||
|
|
@ -51,13 +52,6 @@ static PLI_INT32 my_mcd_printf(PLI_UINT32 mcd, const char *fmt, ...)
|
|||
return r;
|
||||
}
|
||||
|
||||
struct timeformat_info_s {
|
||||
int units;
|
||||
unsigned prec;
|
||||
char*suff;
|
||||
unsigned width;
|
||||
};
|
||||
|
||||
struct timeformat_info_s timeformat_info = { 0, 0, 0, 20 };
|
||||
|
||||
struct strobe_cb_info {
|
||||
|
|
@ -1566,6 +1560,9 @@ void sys_display_register()
|
|||
|
||||
/*
|
||||
* $Log: sys_display.c,v $
|
||||
* Revision 1.72 2006/08/12 03:38:12 steve
|
||||
* scanf support for real values.
|
||||
*
|
||||
* Revision 1.71 2004/10/04 01:10:58 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: sys_priv.h,v 1.5 2004/01/21 01:22:53 steve Exp $"
|
||||
#ident "$Id: sys_priv.h,v 1.6 2006/08/12 03:38:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_config.h"
|
||||
|
|
@ -47,8 +47,21 @@ extern int is_constant(vpiHandle obj);
|
|||
|
||||
extern PLI_UINT64 timerec_to_time64(const struct t_vpi_time*time);
|
||||
|
||||
struct timeformat_info_s {
|
||||
int units;
|
||||
unsigned prec;
|
||||
char*suff;
|
||||
unsigned width;
|
||||
};
|
||||
|
||||
extern struct timeformat_info_s timeformat_info;
|
||||
|
||||
|
||||
/*
|
||||
* $Log: sys_priv.h,v $
|
||||
* Revision 1.6 2006/08/12 03:38:12 steve
|
||||
* scanf support for real values.
|
||||
*
|
||||
* Revision 1.5 2004/01/21 01:22:53 steve
|
||||
* Give the vip directory its own configure and vpi_config.h
|
||||
*
|
||||
|
|
|
|||
138
vpi/sys_scanf.c
138
vpi/sys_scanf.c
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: sys_scanf.c,v 1.1 2006/08/03 05:06:04 steve Exp $"
|
||||
#ident "$Id: sys_scanf.c,v 1.2 2006/08/12 03:38:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_user.h"
|
||||
|
|
@ -26,6 +26,7 @@
|
|||
# include <string.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <math.h>
|
||||
# include <assert.h>
|
||||
|
||||
struct byte_source {
|
||||
|
|
@ -60,6 +61,121 @@ static void byte_ungetc(struct byte_source*src, int ch)
|
|||
}
|
||||
|
||||
|
||||
static int sys_fscanf_compiletf(char*name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function matches the input characters of a floating point
|
||||
* number and generates a floating point (double) from that string.
|
||||
*/
|
||||
static double float_string(struct byte_source*src)
|
||||
{
|
||||
int ch;
|
||||
char*str = 0;
|
||||
size_t len;
|
||||
double sign_flag = 1.0;
|
||||
|
||||
ch = byte_getc(src);
|
||||
|
||||
if (ch == '+') {
|
||||
sign_flag = 1.0;
|
||||
ch = byte_getc(src);
|
||||
} else if (ch == '-') {
|
||||
sign_flag = -1.0;
|
||||
ch = byte_getc(src);
|
||||
}
|
||||
|
||||
str = malloc(1);
|
||||
len = 0;
|
||||
*str = 0;
|
||||
|
||||
while (isdigit(ch)) {
|
||||
str = realloc(str, len+2);
|
||||
str[len++] = ch;
|
||||
ch = byte_getc(src);
|
||||
}
|
||||
|
||||
if (ch == '.') {
|
||||
str = realloc(str, len+2);
|
||||
str[len++] = ch;
|
||||
ch = byte_getc(src);
|
||||
while (isdigit(ch)) {
|
||||
str = realloc(str, len+2);
|
||||
str[len++] = ch;
|
||||
ch = byte_getc(src);
|
||||
}
|
||||
}
|
||||
|
||||
if (ch == 'e' || ch == 'E') {
|
||||
str = realloc(str, len+2);
|
||||
str[len++] = ch;
|
||||
ch = byte_getc(src);
|
||||
|
||||
if (ch == '-' || ch == '+') {
|
||||
str = realloc(str, len+2);
|
||||
str[len++] = ch;
|
||||
ch - byte_getc(src);
|
||||
}
|
||||
|
||||
while (isdigit(ch)) {
|
||||
src = realloc(str, len+2);
|
||||
str[len++] = ch;
|
||||
ch = byte_getc(src);
|
||||
}
|
||||
}
|
||||
|
||||
str[len] = 0;
|
||||
|
||||
sign_flag *= strtod(str, 0);
|
||||
free(str);
|
||||
|
||||
if (ch != EOF)
|
||||
byte_ungetc(src, ch);
|
||||
|
||||
return sign_flag;
|
||||
}
|
||||
|
||||
static int scan_format_float(struct byte_source*src,
|
||||
vpiHandle arg)
|
||||
{
|
||||
s_vpi_value val;
|
||||
|
||||
val.format = vpiRealVal;
|
||||
val.value.real = float_string(src);
|
||||
vpi_put_value(arg, &val, 0, vpiNoDelay);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int scan_format_float_time(vpiHandle sys,
|
||||
struct byte_source*src,
|
||||
vpiHandle arg)
|
||||
{
|
||||
vpiHandle scope = vpi_handle(vpiScope, sys);
|
||||
int time_units = vpi_get(vpiTimeUnit, scope);
|
||||
double scale;
|
||||
|
||||
s_vpi_value val;
|
||||
|
||||
val.format = vpiRealVal;
|
||||
val.value.real = float_string(src);
|
||||
|
||||
/* Round the value to the specified precision. Handle this bit
|
||||
by shifting the decimal point to the precision where we
|
||||
want to round, do the rounding, then shift the point back */
|
||||
scale = pow(10.0, timeformat_info.prec);
|
||||
val.value.real = round(val.value.real*scale) / scale;
|
||||
|
||||
/* Change the units from the timeformat to the timescale. */
|
||||
scale = pow(10.0, timeformat_info.units - time_units);
|
||||
val.value.real *= scale;
|
||||
vpi_put_value(arg, &val, 0, vpiNoDelay);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The $fscanf and $sscanf functions are the same except for the first
|
||||
* argument, which is the source. The wrapper functions below peel off
|
||||
|
|
@ -180,7 +296,6 @@ static int scan_format(vpiHandle sys, struct byte_source*src, vpiHandle argv)
|
|||
rc += 1;
|
||||
break;
|
||||
|
||||
|
||||
case 'd':
|
||||
/* Decimal integer */
|
||||
ch = byte_getc(src);
|
||||
|
|
@ -203,6 +318,14 @@ static int scan_format(vpiHandle sys, struct byte_source*src, vpiHandle argv)
|
|||
rc += 1;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
case 'f':
|
||||
case 'g':
|
||||
item = vpi_scan(argv);
|
||||
assert(item);
|
||||
rc += scan_format_float(src, item);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case 'x':
|
||||
/* Hex integer */
|
||||
|
|
@ -264,6 +387,12 @@ static int scan_format(vpiHandle sys, struct byte_source*src, vpiHandle argv)
|
|||
rc += 1;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
item = vpi_scan(argv);
|
||||
assert(item);
|
||||
rc += scan_format_float_time(sys, src, item);
|
||||
break;
|
||||
|
||||
default:
|
||||
vpi_printf("$scanf: Unknown format code: %c\n", code);
|
||||
break;
|
||||
|
|
@ -281,11 +410,6 @@ static int scan_format(vpiHandle sys, struct byte_source*src, vpiHandle argv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int sys_fscanf_compiletf(char*name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sys_fscanf_calltf(char*name)
|
||||
{
|
||||
s_vpi_value val;
|
||||
|
|
|
|||
Loading…
Reference in New Issue