Use a common routine to get and check the FD/MCD

This commit is contained in:
Cary R 2020-05-16 21:05:44 -07:00
parent 0a06ecb203
commit 38d16e5f2f
4 changed files with 45 additions and 77 deletions

View File

@ -1283,28 +1283,12 @@ static PLI_INT32 sys_display_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name)
/* Get the file/MC descriptor and verify it is valid. */ /* Get the file/MC descriptor and verify it is valid. */
if (name[1] == 'f') { if (name[1] == 'f') {
errno = 0; vpiHandle fd = vpi_scan(argv);
vpiHandle arg = vpi_scan(argv); if (get_fd_mcd_from_arg(&fd_mcd, fd, callh, name)) {
val.format = vpiIntVal;
vpi_get_value(arg, &val);
fd_mcd = val.value.integer;
/* If the MCD is zero we have nothing to do so just return. */
if (fd_mcd == 0) {
vpi_free_object(argv); vpi_free_object(argv);
return 0; return 0;
} }
} else if (strncmp(name, "$sformatf", 9) == 0) {
if (! is_valid_fd_mcd(fd_mcd)) {
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
vpi_printf("invalid file descriptor/MCD (0x%x) given "
"to %s.\n", (unsigned int)fd_mcd, name);
errno = EBADF;
vpi_free_object(argv);
return 0;
}
} else if (strncmp(name,"$sformatf",9) == 0) {
/* return as a string */ /* return as a string */
fd_mcd = 0; fd_mcd = 0;
} else { } else {
@ -1396,28 +1380,12 @@ static PLI_INT32 sys_strobe_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
/* Get the file/MC descriptor and verify it is valid. */ /* Get the file/MC descriptor and verify it is valid. */
if (name[1] == 'f') { if (name[1] == 'f') {
errno = 0; vpiHandle fd = vpi_scan(argv);
vpiHandle arg = vpi_scan(argv); if (get_fd_mcd_from_arg(&fd_mcd, fd, callh, name)) {
s_vpi_value val;
val.format = vpiIntVal;
vpi_get_value(arg, &val);
fd_mcd = val.value.integer;
/* If the MCD is zero we have nothing to do so just return. */
if (fd_mcd == 0) {
vpi_free_object(argv); vpi_free_object(argv);
return 0; return 0;
} }
if (! is_valid_fd_mcd(fd_mcd)) {
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
vpi_printf("invalid file descriptor/MCD (0x%x) given "
"to %s.\n", (unsigned int)fd_mcd, name);
errno = EBADF;
vpi_free_object(argv);
return 0;
}
} else { } else {
fd_mcd = 1; fd_mcd = 1;
} }

View File

@ -211,33 +211,17 @@ static PLI_INT32 sys_fclose_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle argv = vpi_iterate(vpiArgument, callh);
vpiHandle fd = vpi_scan(argv); vpiHandle fd = vpi_scan(argv);
s_vpi_value val;
PLI_UINT32 fd_mcd; PLI_UINT32 fd_mcd;
errno = 0;
vpi_free_object(argv); vpi_free_object(argv);
/* Get the file/MC descriptor and verify that it is valid. */ /* Get the file/MC descriptor and verify that it is valid. */
val.format = vpiIntVal; if (get_fd_mcd_from_arg(&fd_mcd, fd, callh, name)) return 0;
vpi_get_value(fd, &val);
fd_mcd = val.value.integer;
/* If the MCD is zero we have nothing to do so just return. */
if (fd_mcd == 0) return 0;
if (! is_valid_fd_mcd(fd_mcd)) {
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
vpi_printf("invalid file descriptor/MCD (0x%x) given to %s.\n",
(unsigned int)fd_mcd, name);
errno = EBADF;
return 0;
}
/* We need to cancel any active $fstrobe()'s for this FD/MCD. /* We need to cancel any active $fstrobe()'s for this FD/MCD.
* For now we check in the strobe callback and skip the output * For now we check in the strobe callback and skip the output
* generation when needed. */ * generation when needed. */
vpi_mcd_close(fd_mcd); fd_mcd = vpi_mcd_close(fd_mcd);
return 0; return 0;
} }
@ -249,10 +233,8 @@ static PLI_INT32 sys_fflush_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
{ {
vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle argv = vpi_iterate(vpiArgument, callh);
vpiHandle arg; vpiHandle fd;
s_vpi_value val;
PLI_UINT32 fd_mcd; PLI_UINT32 fd_mcd;
errno = 0;
/* If we have no argument then flush all the streams. */ /* If we have no argument then flush all the streams. */
if (argv == 0) { if (argv == 0) {
@ -261,30 +243,14 @@ static PLI_INT32 sys_fflush_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
} }
/* Get the file/MC descriptor and verify that it is valid. */ /* Get the file/MC descriptor and verify that it is valid. */
arg = vpi_scan(argv); fd = vpi_scan(argv);
vpi_free_object(argv); vpi_free_object(argv);
val.format = vpiIntVal; if (get_fd_mcd_from_arg(&fd_mcd, fd, callh, name)) return 0;
vpi_get_value(arg, &val);
fd_mcd = val.value.integer;
/* If the MCD is zero we have nothing to do so just return. */
if (fd_mcd == 0) return 0;
if (! is_valid_fd_mcd(fd_mcd)) {
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
vpi_printf("invalid file descriptor/MCD (0x%x) given to %s.\n",
(unsigned int)fd_mcd, name);
errno = EBADF;
return 0;
}
if (IS_MCD(fd_mcd)) { if (IS_MCD(fd_mcd)) {
vpi_mcd_flush(fd_mcd); vpi_mcd_flush(fd_mcd);
} else { } else {
/* If we have a valid file descriptor flush the file. */ fflush(vpi_get_file(fd_mcd));
FILE *fp = vpi_get_file(fd_mcd);
if (fp) fflush(fp);
} }
return 0; return 0;

View File

@ -20,6 +20,7 @@
#include "sys_priv.h" #include "sys_priv.h"
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
#include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "ivl_alloc.h" #include "ivl_alloc.h"
@ -266,6 +267,37 @@ unsigned is_valid_fd_mcd(PLI_UINT32 fd_mcd)
return 1; return 1;
} }
/*
* Get a FD/MCD from the given argument and check if it is valid. Return the
* FD/MCD in the fd_mcd argument and return 0 if it is valid and 1 if it is
* invalid. We do not print a warning mesage if the FD/MCD is zero.
*/
unsigned get_fd_mcd_from_arg(PLI_UINT32 *fd_mcd, vpiHandle arg,
vpiHandle callh, const char *name)
{
s_vpi_value val;
val.format = vpiIntVal;
vpi_get_value(arg, &val);
*fd_mcd = val.value.integer;
if (*fd_mcd == 0) return 1;
errno = 0;
if (! is_valid_fd_mcd(*fd_mcd)) {
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
vpi_printf("invalid %s (0x%x) given to %s().\n",
IS_MCD(*fd_mcd) ? "MCD" : "file descriptor",
(unsigned int)*fd_mcd,
name);
errno = EBADF;
return 1;
}
return 0;
}
/* /*
* Find the enclosing module. If there is no enclosing module (which can be * Find the enclosing module. If there is no enclosing module (which can be

View File

@ -59,6 +59,8 @@ extern unsigned is_numeric_obj(vpiHandle obj);
extern unsigned is_string_obj(vpiHandle obj); extern unsigned is_string_obj(vpiHandle obj);
extern unsigned is_valid_fd_mcd(PLI_UINT32 fd_mcd); extern unsigned is_valid_fd_mcd(PLI_UINT32 fd_mcd);
extern unsigned get_fd_mcd_from_arg(PLI_UINT32 *fd_mcd, vpiHandle arg,
vpiHandle callh, const char *name);
extern vpiHandle sys_func_module(vpiHandle obj); extern vpiHandle sys_func_module(vpiHandle obj);