Implement $ftell, $fseek and $rewind system functions.
This patch implements the $ftell, $fseek and $rewind system function.
This commit is contained in:
parent
965374acf9
commit
63ca4e6d41
224
vpi/sys_fileio.c
224
vpi/sys_fileio.c
|
|
@ -126,13 +126,8 @@ static PLI_INT32 sys_fopen_calltf(PLI_BYTE8*name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static PLI_INT32 sys_fopen_sizetf(PLI_BYTE8*x)
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
/*
|
||||
* Implement the $fopenr(), $fopenw() and $fopena() systen functions
|
||||
* Implement the $fopenr(), $fopenw() and $fopena() system functions
|
||||
* from Chris Spear's File I/O for Verilog.
|
||||
*/
|
||||
static PLI_INT32 sys_fopenrwa_compiletf(PLI_BYTE8*name)
|
||||
|
|
@ -329,11 +324,6 @@ static PLI_INT32 sys_fgetc_calltf(PLI_BYTE8*name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static PLI_INT32 sys_fgetc_sizetf(PLI_BYTE8*x)
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
static PLI_INT32 sys_fgets_compiletf(PLI_BYTE8*name)
|
||||
{
|
||||
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
|
||||
|
|
@ -489,13 +479,7 @@ static PLI_INT32 sys_ungetc_calltf(PLI_BYTE8*name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static PLI_INT32 sys_ungetc_sizetf(PLI_BYTE8*x)
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
/* $feof() is from 1364-2005. */
|
||||
static PLI_INT32 sys_feof_compiletf(PLI_BYTE8 *ud)
|
||||
static PLI_INT32 sys_check_fd_compiletf(PLI_BYTE8 *ud)
|
||||
{
|
||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||
|
|
@ -535,11 +519,45 @@ static PLI_INT32 sys_feof_compiletf(PLI_BYTE8 *ud)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static PLI_INT32 sys_feof_calltf(PLI_BYTE8 *ud)
|
||||
static PLI_INT32 sys_rewind_calltf(PLI_BYTE8 *ud)
|
||||
{
|
||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||
vpiHandle item = vpi_scan(argv);;
|
||||
vpiHandle item = vpi_scan(argv);
|
||||
s_vpi_value val;
|
||||
PLI_INT32 fd;
|
||||
FILE *fp;
|
||||
|
||||
/* Get the file pointer. */
|
||||
vpi_free_object(argv);
|
||||
val.format = vpiIntVal;
|
||||
vpi_get_value(item, &val);
|
||||
fd = val.value.integer;
|
||||
if (IS_MCD(fd)) {
|
||||
vpi_printf("ERROR: %s cannot be used with a MCD.\n", ud);
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
fp = vpi_get_file(fd);
|
||||
|
||||
/* If we have a valid file descriptor rewind the file. */
|
||||
if (!fp) {
|
||||
val.value.integer = EOF;
|
||||
} else {
|
||||
rewind(fp);
|
||||
val.value.integer = 0;
|
||||
}
|
||||
vpi_put_value(callh, &val, 0 , vpiNoDelay);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* $feof() is from 1364-2005. */
|
||||
static PLI_INT32 sys_ftell_feof_calltf(PLI_BYTE8 *ud)
|
||||
{
|
||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||
vpiHandle item = vpi_scan(argv);
|
||||
s_vpi_value val;
|
||||
PLI_INT32 fd;
|
||||
FILE *fp;
|
||||
|
|
@ -557,18 +575,134 @@ static PLI_INT32 sys_feof_calltf(PLI_BYTE8 *ud)
|
|||
fp = vpi_get_file(fd);
|
||||
|
||||
/* If we do not have a valid file descriptor return EOF, otherwise
|
||||
* check for EOF and return that value. */
|
||||
* return that value. */
|
||||
if (!fp) {
|
||||
val.value.integer = EOF;
|
||||
} else {
|
||||
val.value.integer = feof(fp);
|
||||
if (ud[2] == 'e') {
|
||||
val.value.integer = feof(fp);
|
||||
} else {
|
||||
val.value.integer = ftell(fp);
|
||||
}
|
||||
}
|
||||
vpi_put_value(callh, &val, 0 , vpiNoDelay);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PLI_INT32 sys_feof_sizetf(PLI_BYTE8 *ud)
|
||||
static PLI_INT32 sys_fseek_compiletf(PLI_BYTE8 *ud)
|
||||
{
|
||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||
vpiHandle item;
|
||||
PLI_INT32 type;
|
||||
|
||||
/* Check that there is an argument. */
|
||||
if (argv == 0) {
|
||||
vpi_printf("ERROR: %s requires three arguments.\n", ud);
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
/* Check that the file descriptor is the right type. */
|
||||
item = vpi_scan(argv);
|
||||
type = vpi_get(vpiType, item);
|
||||
switch (type) {
|
||||
case vpiReg:
|
||||
case vpiRealVal:
|
||||
case vpiIntegerVar:
|
||||
break;
|
||||
default:
|
||||
vpi_printf("ERROR: %s fd parameter must be integral", ud);
|
||||
vpi_printf(", got vpiType=%d\n", type);
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check that there is an offset argument. */
|
||||
item = vpi_scan(argv);
|
||||
if (item == 0) {
|
||||
vpi_printf("ERROR: %s is missing an offset and operation "
|
||||
"argument.\n", ud);
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check that there is an operation argument. */
|
||||
item = vpi_scan(argv);
|
||||
if (item == 0) {
|
||||
vpi_printf("ERROR: %s is missing an operation argument.\n", ud);
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check that there is at most one argument. */
|
||||
item = vpi_scan(argv);
|
||||
if (item != 0) {
|
||||
vpi_printf("ERROR: %s takes at most three argument.\n", ud);
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vpi_scan returning 0 (NULL) has already freed argv. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PLI_INT32 sys_fseek_calltf(PLI_BYTE8 *ud)
|
||||
{
|
||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||
vpiHandle item;
|
||||
s_vpi_value val;
|
||||
PLI_INT32 fd, offset, oper;
|
||||
FILE *fp;
|
||||
|
||||
val.format = vpiIntVal;
|
||||
|
||||
/* Get the file pointer. */
|
||||
item = vpi_scan(argv);
|
||||
vpi_get_value(item, &val);
|
||||
fd = val.value.integer;
|
||||
if (IS_MCD(fd)) {
|
||||
vpi_printf("ERROR: %s cannot be used with a MCD.\n", ud);
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
fp = vpi_get_file(fd);
|
||||
|
||||
/* Get the offset. */
|
||||
item = vpi_scan(argv);
|
||||
vpi_get_value(item, &val);
|
||||
offset = val.value.integer;
|
||||
|
||||
/* Get the operation. */
|
||||
item = vpi_scan(argv);
|
||||
vpi_get_value(item, &val);
|
||||
oper = val.value.integer;
|
||||
/* Should this translate to the SEEK_??? codes? */
|
||||
/* What about verifying offset value vs operation ($fseek(fd, -1, 0))? */
|
||||
if ((oper < 0) || (oper > 2)) {
|
||||
vpi_printf("ERROR: %s's operation must be 0, 1 or 2 given %d.\n",
|
||||
ud, oper);
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If we do not have a valid file descriptor return EOF, otherwise
|
||||
* return that value. */
|
||||
if (!fp) {
|
||||
val.value.integer = EOF;
|
||||
} else {
|
||||
fseek(fp, offset, oper);
|
||||
val.value.integer = 0;
|
||||
}
|
||||
vpi_put_value(callh, &val, 0 , vpiNoDelay);
|
||||
|
||||
vpi_free_object(argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PLI_INT32 sys_integer_sizetf(PLI_BYTE8 *ud)
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
|
@ -582,7 +716,7 @@ void sys_fileio_register()
|
|||
tf_data.tfname = "$fopen";
|
||||
tf_data.calltf = sys_fopen_calltf;
|
||||
tf_data.compiletf = sys_fopen_compiletf;
|
||||
tf_data.sizetf = sys_fopen_sizetf;
|
||||
tf_data.sizetf = sys_integer_sizetf;
|
||||
tf_data.user_data = "$fopen";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
|
|
@ -591,7 +725,7 @@ void sys_fileio_register()
|
|||
tf_data.tfname = "$fopenr";
|
||||
tf_data.calltf = sys_fopenrwa_calltf;
|
||||
tf_data.compiletf = sys_fopenrwa_compiletf;
|
||||
tf_data.sizetf = sys_fopen_sizetf;
|
||||
tf_data.sizetf = sys_integer_sizetf;
|
||||
tf_data.user_data = "$fopenr";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
|
|
@ -638,7 +772,7 @@ void sys_fileio_register()
|
|||
tf_data.tfname = "$fgetc";
|
||||
tf_data.calltf = sys_fgetc_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = sys_fgetc_sizetf;
|
||||
tf_data.sizetf = sys_integer_sizetf;
|
||||
tf_data.user_data = "$fgetc";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
|
|
@ -658,18 +792,48 @@ void sys_fileio_register()
|
|||
tf_data.tfname = "$ungetc";
|
||||
tf_data.calltf = sys_ungetc_calltf;
|
||||
tf_data.compiletf = sys_ungetc_compiletf;
|
||||
tf_data.sizetf = sys_ungetc_sizetf;
|
||||
tf_data.sizetf = sys_integer_sizetf;
|
||||
tf_data.user_data = "$ungetc";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
//============================== ftell
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.sysfunctype = vpiSysFuncInt;
|
||||
tf_data.tfname = "$ftell";
|
||||
tf_data.calltf = sys_ftell_feof_calltf;
|
||||
tf_data.compiletf = sys_check_fd_compiletf;
|
||||
tf_data.sizetf = sys_integer_sizetf;
|
||||
tf_data.user_data = "$ftell";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
//============================== fseek
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.sysfunctype = vpiSysFuncInt;
|
||||
tf_data.tfname = "$fseek";
|
||||
tf_data.calltf = sys_fseek_calltf;
|
||||
tf_data.compiletf = sys_fseek_compiletf;
|
||||
tf_data.sizetf = sys_integer_sizetf;
|
||||
tf_data.user_data = "$fseek";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
//============================== rewind
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.sysfunctype = vpiSysFuncInt;
|
||||
tf_data.tfname = "$rewind";
|
||||
tf_data.calltf = sys_rewind_calltf;
|
||||
tf_data.compiletf = sys_check_fd_compiletf;
|
||||
tf_data.sizetf = sys_integer_sizetf;
|
||||
tf_data.user_data = "$rewind";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
/* $feof() is from 1364-2005. */
|
||||
//============================== feof
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.sysfunctype = vpiSysFuncInt;
|
||||
tf_data.tfname = "$feof";
|
||||
tf_data.calltf = sys_feof_calltf;
|
||||
tf_data.compiletf = sys_feof_compiletf;
|
||||
tf_data.sizetf = sys_feof_sizetf;
|
||||
tf_data.calltf = sys_ftell_feof_calltf;
|
||||
tf_data.compiletf = sys_check_fd_compiletf;
|
||||
tf_data.sizetf = sys_integer_sizetf;
|
||||
tf_data.user_data = "$feof";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue