Make the $fdisplay/$fwrite family use the string formatting.
This patch makes the $fdisplay() and $fwrite() family of task use the string formatting code. It also adds a compiletf routine for the tasks and a run time check that the FD or MCD is correct. If not it fails instead of just dropping the output. It also cleans up a couple of memory leaks and adds no argument compiletf routines for the $monitoron/$monitoroff tasks.
This commit is contained in:
parent
edc4bc1923
commit
4f26c62207
|
|
@ -1190,6 +1190,12 @@ static PLI_INT32 sys_monitoroff_calltf(PLI_BYTE8*name)
|
||||||
/* Implement $fdisplay and $fwrite.
|
/* Implement $fdisplay and $fwrite.
|
||||||
* Perhaps this could be merged into sys_display_calltf.
|
* Perhaps this could be merged into sys_display_calltf.
|
||||||
*/
|
*/
|
||||||
|
#ifdef USE_OLD_DISPLAY
|
||||||
|
static PLI_INT32 sys_fdisplay_compiletf(PLI_BYTE8*name)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static PLI_INT32 sys_fdisplay_calltf(PLI_BYTE8*name)
|
static PLI_INT32 sys_fdisplay_calltf(PLI_BYTE8*name)
|
||||||
{
|
{
|
||||||
struct strobe_cb_info info;
|
struct strobe_cb_info info;
|
||||||
|
|
@ -1253,6 +1259,7 @@ static PLI_INT32 sys_fdisplay_calltf(PLI_BYTE8*name)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Build the format using the variables that control how the item will
|
/* Build the format using the variables that control how the item will
|
||||||
* be printed. This is used in error messages and directly by the e/f/g
|
* be printed. This is used in error messages and directly by the e/f/g
|
||||||
|
|
@ -1896,6 +1903,7 @@ static unsigned int get_format_char(char **rtn, int ljust, int plus,
|
||||||
* characters into the stream. */
|
* characters into the stream. */
|
||||||
*rtn = malloc(size*sizeof(char));
|
*rtn = malloc(size*sizeof(char));
|
||||||
memcpy(*rtn, result, size);
|
memcpy(*rtn, result, size);
|
||||||
|
free(result);
|
||||||
return size - 1;
|
return size - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2110,6 +2118,7 @@ static char *get_display(unsigned int *rtnsz, struct strobe_cb_info *info)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef USE_OLD_DISPLAY
|
#ifndef USE_OLD_DISPLAY
|
||||||
|
/* This implements both the $display and the $write based tasks. */
|
||||||
static PLI_INT32 sys_display_calltf(PLI_BYTE8 *name)
|
static PLI_INT32 sys_display_calltf(PLI_BYTE8 *name)
|
||||||
{
|
{
|
||||||
vpiHandle callh, argv, scope;
|
vpiHandle callh, argv, scope;
|
||||||
|
|
@ -2122,8 +2131,8 @@ static PLI_INT32 sys_display_calltf(PLI_BYTE8 *name)
|
||||||
|
|
||||||
scope = vpi_handle(vpiScope, callh);
|
scope = vpi_handle(vpiScope, callh);
|
||||||
assert(scope);
|
assert(scope);
|
||||||
/* We could use vpi_get_str(vpiName, callh) to get the task name, but
|
/* We could use vpi_get_str(vpiName, callh) to get the task name,
|
||||||
* name is already defined. */
|
* but name is already defined. */
|
||||||
info.name = name;
|
info.name = name;
|
||||||
info.filename = strdup(vpi_get_str(vpiFile, callh));
|
info.filename = strdup(vpi_get_str(vpiFile, callh));
|
||||||
info.lineno = (int)vpi_get(vpiLineNo, callh);
|
info.lineno = (int)vpi_get(vpiLineNo, callh);
|
||||||
|
|
@ -2131,8 +2140,8 @@ static PLI_INT32 sys_display_calltf(PLI_BYTE8 *name)
|
||||||
info.scope = scope;
|
info.scope = scope;
|
||||||
array_from_iterator(&info, argv);
|
array_from_iterator(&info, argv);
|
||||||
|
|
||||||
/* Because %u and %z may put embedded NULL characters into the returned
|
/* Because %u and %z may put embedded NULL characters into the
|
||||||
* string strlen() may not match the real size! */
|
* returned string strlen() may not match the real size! */
|
||||||
result = get_display(&size, &info);
|
result = get_display(&size, &info);
|
||||||
while (location < size) {
|
while (location < size) {
|
||||||
if (result[location] == '\0') {
|
if (result[location] == '\0') {
|
||||||
|
|
@ -2147,6 +2156,94 @@ static PLI_INT32 sys_display_calltf(PLI_BYTE8 *name)
|
||||||
|
|
||||||
free(info.filename);
|
free(info.filename);
|
||||||
free(info.items);
|
free(info.items);
|
||||||
|
free(result);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This checks both the $fdisplay and the $fwrite based tasks. */
|
||||||
|
static PLI_INT32 sys_fdisplay_compiletf(PLI_BYTE8*name)
|
||||||
|
{
|
||||||
|
vpiHandle callh, argv;
|
||||||
|
|
||||||
|
callh = vpi_handle(vpiSysTfCall, 0);
|
||||||
|
argv = vpi_iterate(vpiArgument, callh);
|
||||||
|
|
||||||
|
/* Check that there is a fd/mcd and that it is numeric. */
|
||||||
|
if (argv == 0) {
|
||||||
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_printf("%s requires at least a file descriptor/MCD.\n", name);
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! is_numeric_obj(vpi_scan(argv))) {
|
||||||
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_printf("%s's file descriptor/MCD must be numeric.\n", name);
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
vpi_free_object(argv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This implements both the $fdisplay and the $fwrite based tasks. */
|
||||||
|
static PLI_INT32 sys_fdisplay_calltf(PLI_BYTE8*name)
|
||||||
|
{
|
||||||
|
vpiHandle callh, argv, scope, arg;
|
||||||
|
struct strobe_cb_info info;
|
||||||
|
s_vpi_value val;
|
||||||
|
PLI_UINT32 fd_mcd;
|
||||||
|
char* result;
|
||||||
|
unsigned int size, location=0;
|
||||||
|
|
||||||
|
callh = vpi_handle(vpiSysTfCall, 0);
|
||||||
|
argv = vpi_iterate(vpiArgument, callh);
|
||||||
|
|
||||||
|
/* Get the file/MC descriptor and verify it is valid. */
|
||||||
|
arg = vpi_scan(argv);
|
||||||
|
val.format = vpiIntVal;
|
||||||
|
vpi_get_value(arg, &val);
|
||||||
|
fd_mcd = val.value.integer;
|
||||||
|
if ((! IS_MCD(fd_mcd) && vpi_get_file(fd_mcd) == NULL) ||
|
||||||
|
( IS_MCD(fd_mcd) && my_mcd_printf(fd_mcd, "") == EOF)) {
|
||||||
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_printf("invalid file descriptor/MCD (0x%x) given to %s.\n",
|
||||||
|
fd_mcd, name);
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
scope = vpi_handle(vpiScope, callh);
|
||||||
|
assert(scope);
|
||||||
|
/* We could use vpi_get_str(vpiName, callh) to get the task name,
|
||||||
|
* but name is already defined. */
|
||||||
|
info.name = name;
|
||||||
|
info.filename = strdup(vpi_get_str(vpiFile, callh));
|
||||||
|
info.lineno = (int)vpi_get(vpiLineNo, callh);
|
||||||
|
info.default_format = get_default_format(name);
|
||||||
|
info.scope = scope;
|
||||||
|
array_from_iterator(&info, argv);
|
||||||
|
|
||||||
|
/* Because %u and %z may put embedded NULL characters into the
|
||||||
|
* returned string strlen() may not match the real size! */
|
||||||
|
result = get_display(&size, &info);
|
||||||
|
while (location < size) {
|
||||||
|
if (result[location] == '\0') {
|
||||||
|
my_mcd_printf(fd_mcd, "\0");
|
||||||
|
location += 1;
|
||||||
|
} else {
|
||||||
|
my_mcd_printf(fd_mcd, "%s", &result[location]);
|
||||||
|
location += strlen(&result[location]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (strncmp(name,"$fdisplay",9) == 0) my_mcd_printf(fd_mcd, "\n");
|
||||||
|
|
||||||
|
free(info.filename);
|
||||||
|
free(info.items);
|
||||||
|
free(result);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -2635,7 +2732,7 @@ void sys_display_register()
|
||||||
tf_data.type = vpiSysTask;
|
tf_data.type = vpiSysTask;
|
||||||
tf_data.tfname = "$monitoron";
|
tf_data.tfname = "$monitoron";
|
||||||
tf_data.calltf = sys_monitoron_calltf;
|
tf_data.calltf = sys_monitoron_calltf;
|
||||||
tf_data.compiletf = 0;
|
tf_data.compiletf = sys_no_arg_compiletf;
|
||||||
tf_data.sizetf = 0;
|
tf_data.sizetf = 0;
|
||||||
tf_data.user_data = "$monitoron";
|
tf_data.user_data = "$monitoron";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
@ -2643,7 +2740,7 @@ void sys_display_register()
|
||||||
tf_data.type = vpiSysTask;
|
tf_data.type = vpiSysTask;
|
||||||
tf_data.tfname = "$monitoroff";
|
tf_data.tfname = "$monitoroff";
|
||||||
tf_data.calltf = sys_monitoroff_calltf;
|
tf_data.calltf = sys_monitoroff_calltf;
|
||||||
tf_data.compiletf = 0;
|
tf_data.compiletf = sys_no_arg_compiletf;
|
||||||
tf_data.sizetf = 0;
|
tf_data.sizetf = 0;
|
||||||
tf_data.user_data = "$monitoroff";
|
tf_data.user_data = "$monitoroff";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
@ -2652,7 +2749,7 @@ void sys_display_register()
|
||||||
tf_data.type = vpiSysTask;
|
tf_data.type = vpiSysTask;
|
||||||
tf_data.tfname = "$fdisplay";
|
tf_data.tfname = "$fdisplay";
|
||||||
tf_data.calltf = sys_fdisplay_calltf;
|
tf_data.calltf = sys_fdisplay_calltf;
|
||||||
tf_data.compiletf = 0;
|
tf_data.compiletf = sys_fdisplay_compiletf;
|
||||||
tf_data.sizetf = 0;
|
tf_data.sizetf = 0;
|
||||||
tf_data.user_data = "$fdisplay";
|
tf_data.user_data = "$fdisplay";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
@ -2660,7 +2757,7 @@ void sys_display_register()
|
||||||
tf_data.type = vpiSysTask;
|
tf_data.type = vpiSysTask;
|
||||||
tf_data.tfname = "$fdisplayh";
|
tf_data.tfname = "$fdisplayh";
|
||||||
tf_data.calltf = sys_fdisplay_calltf;
|
tf_data.calltf = sys_fdisplay_calltf;
|
||||||
tf_data.compiletf = 0;
|
tf_data.compiletf = sys_fdisplay_compiletf;
|
||||||
tf_data.sizetf = 0;
|
tf_data.sizetf = 0;
|
||||||
tf_data.user_data = "$fdisplayh";
|
tf_data.user_data = "$fdisplayh";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
@ -2668,7 +2765,7 @@ void sys_display_register()
|
||||||
tf_data.type = vpiSysTask;
|
tf_data.type = vpiSysTask;
|
||||||
tf_data.tfname = "$fdisplayo";
|
tf_data.tfname = "$fdisplayo";
|
||||||
tf_data.calltf = sys_fdisplay_calltf;
|
tf_data.calltf = sys_fdisplay_calltf;
|
||||||
tf_data.compiletf = 0;
|
tf_data.compiletf = sys_fdisplay_compiletf;
|
||||||
tf_data.sizetf = 0;
|
tf_data.sizetf = 0;
|
||||||
tf_data.user_data = "$fdisplayo";
|
tf_data.user_data = "$fdisplayo";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
@ -2676,7 +2773,7 @@ void sys_display_register()
|
||||||
tf_data.type = vpiSysTask;
|
tf_data.type = vpiSysTask;
|
||||||
tf_data.tfname = "$fdisplayb";
|
tf_data.tfname = "$fdisplayb";
|
||||||
tf_data.calltf = sys_fdisplay_calltf;
|
tf_data.calltf = sys_fdisplay_calltf;
|
||||||
tf_data.compiletf = 0;
|
tf_data.compiletf = sys_fdisplay_compiletf;
|
||||||
tf_data.sizetf = 0;
|
tf_data.sizetf = 0;
|
||||||
tf_data.user_data = "$fdisplayb";
|
tf_data.user_data = "$fdisplayb";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
@ -2685,7 +2782,7 @@ void sys_display_register()
|
||||||
tf_data.type = vpiSysTask;
|
tf_data.type = vpiSysTask;
|
||||||
tf_data.tfname = "$fwrite";
|
tf_data.tfname = "$fwrite";
|
||||||
tf_data.calltf = sys_fdisplay_calltf;
|
tf_data.calltf = sys_fdisplay_calltf;
|
||||||
tf_data.compiletf = 0;
|
tf_data.compiletf = sys_fdisplay_compiletf;
|
||||||
tf_data.sizetf = 0;
|
tf_data.sizetf = 0;
|
||||||
tf_data.user_data = "$fwrite";
|
tf_data.user_data = "$fwrite";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
@ -2693,7 +2790,7 @@ void sys_display_register()
|
||||||
tf_data.type = vpiSysTask;
|
tf_data.type = vpiSysTask;
|
||||||
tf_data.tfname = "$fwriteh";
|
tf_data.tfname = "$fwriteh";
|
||||||
tf_data.calltf = sys_fdisplay_calltf;
|
tf_data.calltf = sys_fdisplay_calltf;
|
||||||
tf_data.compiletf = 0;
|
tf_data.compiletf = sys_fdisplay_compiletf;
|
||||||
tf_data.sizetf = 0;
|
tf_data.sizetf = 0;
|
||||||
tf_data.user_data = "$fwriteh";
|
tf_data.user_data = "$fwriteh";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
@ -2701,7 +2798,7 @@ void sys_display_register()
|
||||||
tf_data.type = vpiSysTask;
|
tf_data.type = vpiSysTask;
|
||||||
tf_data.tfname = "$fwriteo";
|
tf_data.tfname = "$fwriteo";
|
||||||
tf_data.calltf = sys_fdisplay_calltf;
|
tf_data.calltf = sys_fdisplay_calltf;
|
||||||
tf_data.compiletf = 0;
|
tf_data.compiletf = sys_fdisplay_compiletf;
|
||||||
tf_data.sizetf = 0;
|
tf_data.sizetf = 0;
|
||||||
tf_data.user_data = "$fwriteo";
|
tf_data.user_data = "$fwriteo";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
@ -2709,7 +2806,7 @@ void sys_display_register()
|
||||||
tf_data.type = vpiSysTask;
|
tf_data.type = vpiSysTask;
|
||||||
tf_data.tfname = "$fwriteb";
|
tf_data.tfname = "$fwriteb";
|
||||||
tf_data.calltf = sys_fdisplay_calltf;
|
tf_data.calltf = sys_fdisplay_calltf;
|
||||||
tf_data.compiletf = 0;
|
tf_data.compiletf = sys_fdisplay_compiletf;
|
||||||
tf_data.sizetf = 0;
|
tf_data.sizetf = 0;
|
||||||
tf_data.user_data = "$fwriteb";
|
tf_data.user_data = "$fwriteb";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue