Merge branch 'master' into vvp-net-out-rework
This commit is contained in:
commit
aaddbdb0ec
28
dosify.c
28
dosify.c
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -16,9 +16,6 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
|
||||||
#ident "$Id: dosify.c,v 1.5 2003/07/15 16:17:47 steve Exp $"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a simple program to make a dosified copy of the
|
* This is a simple program to make a dosified copy of the
|
||||||
|
|
@ -51,6 +48,7 @@ int main(int argc, char*argv[])
|
||||||
ofile = fopen(argv[2], "wb");
|
ofile = fopen(argv[2], "wb");
|
||||||
if (ofile == 0) {
|
if (ofile == 0) {
|
||||||
fprintf(stderr, "Unable to open %s for output.\n", argv[2]);
|
fprintf(stderr, "Unable to open %s for output.\n", argv[2]);
|
||||||
|
fclose(ifile);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,25 +62,7 @@ int main(int argc, char*argv[])
|
||||||
pr = ch;
|
pr = ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fclose(ifile);
|
||||||
|
fclose(ofile);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* $Log: dosify.c,v $
|
|
||||||
* Revision 1.5 2003/07/15 16:17:47 steve
|
|
||||||
* Fix spelling of ifdef.
|
|
||||||
*
|
|
||||||
* Revision 1.4 2003/07/15 03:49:22 steve
|
|
||||||
* Spelling fixes.
|
|
||||||
*
|
|
||||||
* Revision 1.3 2002/08/12 01:34:58 steve
|
|
||||||
* conditional ident string using autoconfig.
|
|
||||||
*
|
|
||||||
* Revision 1.2 2002/08/11 23:47:04 steve
|
|
||||||
* Add missing Log and Ident strings.
|
|
||||||
*
|
|
||||||
* Revision 1.1 2001/08/03 17:06:47 steve
|
|
||||||
* Add install of examples for Windows.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
# include "sys_priv.h"
|
# include "sys_priv.h"
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
|
# include <errno.h>
|
||||||
# include <ctype.h>
|
# include <ctype.h>
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
|
|
@ -1120,18 +1121,20 @@ static PLI_INT32 sys_display_calltf(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 arg = vpi_scan(argv);
|
vpiHandle arg = vpi_scan(argv);
|
||||||
s_vpi_value val;
|
s_vpi_value val;
|
||||||
val.format = vpiIntVal;
|
val.format = vpiIntVal;
|
||||||
vpi_get_value(arg, &val);
|
vpi_get_value(arg, &val);
|
||||||
fd_mcd = val.value.integer;
|
fd_mcd = val.value.integer;
|
||||||
if ((! IS_MCD(fd_mcd) && vpi_get_file(fd_mcd) == NULL) ||
|
if ((! IS_MCD(fd_mcd) && vpi_get_file(fd_mcd) == NULL) ||
|
||||||
( IS_MCD(fd_mcd) && my_mcd_printf(fd_mcd, "") == EOF)) {
|
( IS_MCD(fd_mcd) && my_mcd_printf(fd_mcd, "") == EOF) ||
|
||||||
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
(! fd_mcd)) {
|
||||||
|
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("invalid file descriptor/MCD (0x%x) given "
|
vpi_printf("invalid file descriptor/MCD (0x%x) given "
|
||||||
"to %s.\n", fd_mcd, name);
|
"to %s.\n", fd_mcd, name);
|
||||||
vpi_control(vpiFinish, 1);
|
errno = EBADF;
|
||||||
vpi_free_object(argv);
|
vpi_free_object(argv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1180,23 +1183,29 @@ static PLI_INT32 sys_display_calltf(PLI_BYTE8 *name)
|
||||||
*/
|
*/
|
||||||
static PLI_INT32 strobe_cb(p_cb_data cb)
|
static PLI_INT32 strobe_cb(p_cb_data cb)
|
||||||
{
|
{
|
||||||
char* result;
|
char* result = NULL;
|
||||||
unsigned int size, location=0;
|
unsigned int size, location=0;
|
||||||
struct strobe_cb_info*info = (struct strobe_cb_info*)cb->user_data;
|
struct strobe_cb_info*info = (struct strobe_cb_info*)cb->user_data;
|
||||||
|
|
||||||
/* Because %u and %z may put embedded NULL characters into the
|
/* We really need to cancel any $fstrobe() calls for a file when it
|
||||||
* returned string strlen() may not match the real size! */
|
* is closed, but for now we will just skip processing the result.
|
||||||
result = get_display(&size, info);
|
* Which has the same basic effect. */
|
||||||
while (location < size) {
|
if ((! IS_MCD(info->fd_mcd) && vpi_get_file(info->fd_mcd) != NULL) ||
|
||||||
if (result[location] == '\0') {
|
( IS_MCD(info->fd_mcd) && my_mcd_printf(info->fd_mcd, "") != EOF)) {
|
||||||
my_mcd_printf(info->fd_mcd, "%c", '\0');
|
/* Because %u and %z may put embedded NULL characters into the
|
||||||
location += 1;
|
* returned string strlen() may not match the real size! */
|
||||||
} else {
|
result = get_display(&size, info);
|
||||||
my_mcd_printf(info->fd_mcd, "%s", &result[location]);
|
while (location < size) {
|
||||||
location += strlen(&result[location]);
|
if (result[location] == '\0') {
|
||||||
|
my_mcd_printf(info->fd_mcd, "%c", '\0');
|
||||||
|
location += 1;
|
||||||
|
} else {
|
||||||
|
my_mcd_printf(info->fd_mcd, "%s", &result[location]);
|
||||||
|
location += strlen(&result[location]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
my_mcd_printf(info->fd_mcd, "\n");
|
||||||
}
|
}
|
||||||
my_mcd_printf(info->fd_mcd, "\n");
|
|
||||||
|
|
||||||
free(info->filename);
|
free(info->filename);
|
||||||
free(info->items);
|
free(info->items);
|
||||||
|
|
@ -1226,18 +1235,20 @@ static PLI_INT32 sys_strobe_calltf(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 arg = vpi_scan(argv);
|
vpiHandle arg = vpi_scan(argv);
|
||||||
s_vpi_value val;
|
s_vpi_value val;
|
||||||
val.format = vpiIntVal;
|
val.format = vpiIntVal;
|
||||||
vpi_get_value(arg, &val);
|
vpi_get_value(arg, &val);
|
||||||
fd_mcd = val.value.integer;
|
fd_mcd = val.value.integer;
|
||||||
if ((! IS_MCD(fd_mcd) && vpi_get_file(fd_mcd) == NULL) ||
|
if ((! IS_MCD(fd_mcd) && vpi_get_file(fd_mcd) == NULL) ||
|
||||||
( IS_MCD(fd_mcd) && my_mcd_printf(fd_mcd, "") == EOF)) {
|
( IS_MCD(fd_mcd) && my_mcd_printf(fd_mcd, "") == EOF) ||
|
||||||
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
(! fd_mcd)) {
|
||||||
|
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("invalid file descriptor/MCD (0x%x) given "
|
vpi_printf("invalid file descriptor/MCD (0x%x) given "
|
||||||
"to %s.\n", fd_mcd, name);
|
"to %s.\n", fd_mcd, name);
|
||||||
vpi_control(vpiFinish, 1);
|
errno = EBADF;
|
||||||
vpi_free_object(argv);
|
vpi_free_object(argv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
208
vpi/sys_fileio.c
208
vpi/sys_fileio.c
|
|
@ -21,13 +21,13 @@
|
||||||
# include "sys_priv.h"
|
# include "sys_priv.h"
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
# include <ctype.h>
|
# include <ctype.h>
|
||||||
|
# include <errno.h>
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
|
|
||||||
#define IS_MCD(mcd) !((mcd)>>31&1)
|
#define IS_MCD(mcd) !((mcd)>>31&1)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Implement the $fopen system function.
|
* Implement the $fopen system function.
|
||||||
*/
|
*/
|
||||||
|
|
@ -83,6 +83,8 @@ static PLI_INT32 sys_fopen_calltf(PLI_BYTE8*name)
|
||||||
vpiHandle fileh = vpi_scan(argv);
|
vpiHandle fileh = vpi_scan(argv);
|
||||||
char *fname;
|
char *fname;
|
||||||
vpiHandle mode = vpi_scan(argv);
|
vpiHandle mode = vpi_scan(argv);
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
/* Get the mode handle if it exists. */
|
/* Get the mode handle if it exists. */
|
||||||
if (mode) {
|
if (mode) {
|
||||||
char *esc_md;
|
char *esc_md;
|
||||||
|
|
@ -180,7 +182,7 @@ static PLI_INT32 sys_fopenrwa_calltf(PLI_BYTE8*name)
|
||||||
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||||
s_vpi_value val;
|
s_vpi_value val;
|
||||||
char *mode, *fname;
|
char *mode, *fname;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
/* Get the mode. */
|
/* Get the mode. */
|
||||||
mode = name + strlen(name) - 1;
|
mode = name + strlen(name) - 1;
|
||||||
|
|
@ -210,6 +212,7 @@ static PLI_INT32 sys_fclose_calltf(PLI_BYTE8*name)
|
||||||
s_vpi_value val;
|
s_vpi_value val;
|
||||||
PLI_UINT32 fd_mcd;
|
PLI_UINT32 fd_mcd;
|
||||||
char *str = ""; /* This prevents the compiler from complaining. */
|
char *str = ""; /* This prevents the compiler from complaining. */
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
vpi_free_object(argv);
|
vpi_free_object(argv);
|
||||||
|
|
||||||
|
|
@ -219,15 +222,19 @@ static PLI_INT32 sys_fclose_calltf(PLI_BYTE8*name)
|
||||||
fd_mcd = val.value.integer;
|
fd_mcd = val.value.integer;
|
||||||
|
|
||||||
if ((! IS_MCD(fd_mcd) && vpi_get_file(fd_mcd) == NULL) ||
|
if ((! IS_MCD(fd_mcd) && vpi_get_file(fd_mcd) == NULL) ||
|
||||||
( IS_MCD(fd_mcd) && vpi_mcd_printf(fd_mcd, str) == EOF)) {
|
( IS_MCD(fd_mcd) && vpi_mcd_printf(fd_mcd, str) == EOF) ||
|
||||||
|
(! fd_mcd)) {
|
||||||
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("invalid file descriptor/MCD (0x%x) given to %s.\n",
|
vpi_printf("invalid file descriptor/MCD (0x%x) given to %s.\n",
|
||||||
fd_mcd, name);
|
fd_mcd, name);
|
||||||
|
errno = EBADF;
|
||||||
return 0;
|
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
|
||||||
|
* generation when needed. */
|
||||||
vpi_mcd_close(fd_mcd);
|
vpi_mcd_close(fd_mcd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -245,6 +252,7 @@ static PLI_INT32 sys_fflush_calltf(PLI_BYTE8*name)
|
||||||
PLI_UINT32 fd_mcd;
|
PLI_UINT32 fd_mcd;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *str = ""; /* This prevents the compiler from complaining. */
|
char *str = ""; /* This prevents the compiler from complaining. */
|
||||||
|
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) {
|
||||||
|
|
@ -260,11 +268,13 @@ static PLI_INT32 sys_fflush_calltf(PLI_BYTE8*name)
|
||||||
fd_mcd = val.value.integer;
|
fd_mcd = val.value.integer;
|
||||||
|
|
||||||
if ((! IS_MCD(fd_mcd) && vpi_get_file(fd_mcd) == NULL) ||
|
if ((! IS_MCD(fd_mcd) && vpi_get_file(fd_mcd) == NULL) ||
|
||||||
( IS_MCD(fd_mcd) && vpi_mcd_printf(fd_mcd, str) == EOF)) {
|
( IS_MCD(fd_mcd) && vpi_mcd_printf(fd_mcd, str) == EOF) ||
|
||||||
|
(! fd_mcd)) {
|
||||||
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("invalid file descriptor/MCD (0x%x) given to %s.\n",
|
vpi_printf("invalid file descriptor/MCD (0x%x) given to %s.\n",
|
||||||
fd_mcd, name);
|
fd_mcd, name);
|
||||||
|
errno = EBADF;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -288,7 +298,7 @@ static PLI_INT32 sys_fputc_calltf(PLI_BYTE8*name)
|
||||||
PLI_UINT32 fd_mcd;
|
PLI_UINT32 fd_mcd;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
unsigned char chr;
|
unsigned char chr;
|
||||||
(void) name; /* Not used! */
|
errno = 0;
|
||||||
|
|
||||||
/* Get the character. */
|
/* Get the character. */
|
||||||
arg = vpi_scan(argv);
|
arg = vpi_scan(argv);
|
||||||
|
|
@ -312,9 +322,12 @@ static PLI_INT32 sys_fputc_calltf(PLI_BYTE8*name)
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
||||||
name);
|
name);
|
||||||
|
errno = EBADF;
|
||||||
val.value.integer = EOF;
|
val.value.integer = EOF;
|
||||||
} else
|
} else {
|
||||||
val.value.integer = fputc(chr, fp);
|
val.value.integer = fputc(chr, fp);
|
||||||
|
if (val.value.integer != EOF) val.value.integer = 0;
|
||||||
|
}
|
||||||
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -378,7 +391,7 @@ static PLI_INT32 sys_fgets_calltf(PLI_BYTE8*name)
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
PLI_INT32 reg_size;
|
PLI_INT32 reg_size;
|
||||||
char*text;
|
char*text;
|
||||||
(void) name; /* Not used! */
|
errno = 0;
|
||||||
|
|
||||||
/* Get the register handle. */
|
/* Get the register handle. */
|
||||||
regh = vpi_scan(argv);
|
regh = vpi_scan(argv);
|
||||||
|
|
@ -397,6 +410,7 @@ static PLI_INT32 sys_fgets_calltf(PLI_BYTE8*name)
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
||||||
name);
|
name);
|
||||||
|
errno = EBADF;
|
||||||
val.format = vpiIntVal;
|
val.format = vpiIntVal;
|
||||||
val.value.integer = 0;
|
val.value.integer = 0;
|
||||||
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
||||||
|
|
@ -566,6 +580,7 @@ static PLI_INT32 sys_fread_calltf(PLI_BYTE8*name)
|
||||||
unsigned is_mem, idx, bpe, words;
|
unsigned is_mem, idx, bpe, words;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
s_vpi_vecval *vector;
|
s_vpi_vecval *vector;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
/* Get the register/memory. */
|
/* Get the register/memory. */
|
||||||
mem_reg = vpi_scan(argv);
|
mem_reg = vpi_scan(argv);
|
||||||
|
|
@ -583,6 +598,7 @@ static PLI_INT32 sys_fread_calltf(PLI_BYTE8*name)
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
||||||
name);
|
name);
|
||||||
|
errno = EBADF;
|
||||||
val.format = vpiIntVal;
|
val.format = vpiIntVal;
|
||||||
val.value.integer = 0;
|
val.value.integer = 0;
|
||||||
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
||||||
|
|
@ -693,8 +709,8 @@ static PLI_INT32 sys_ungetc_calltf(PLI_BYTE8*name)
|
||||||
s_vpi_value val;
|
s_vpi_value val;
|
||||||
PLI_UINT32 fd_mcd;
|
PLI_UINT32 fd_mcd;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
unsigned char chr;
|
int chr;
|
||||||
(void) name; /* Not used! */
|
errno = 0;
|
||||||
|
|
||||||
/* Get the character. */
|
/* Get the character. */
|
||||||
arg = vpi_scan(argv);
|
arg = vpi_scan(argv);
|
||||||
|
|
@ -716,6 +732,7 @@ static PLI_INT32 sys_ungetc_calltf(PLI_BYTE8*name)
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
||||||
name);
|
name);
|
||||||
|
errno = EBADF;
|
||||||
val.format = vpiIntVal;
|
val.format = vpiIntVal;
|
||||||
val.value.integer = EOF;
|
val.value.integer = EOF;
|
||||||
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
||||||
|
|
@ -725,6 +742,7 @@ static PLI_INT32 sys_ungetc_calltf(PLI_BYTE8*name)
|
||||||
/* ungetc the character and return the result. */
|
/* ungetc the character and return the result. */
|
||||||
val.format = vpiIntVal;
|
val.format = vpiIntVal;
|
||||||
val.value.integer = ungetc(chr, fp);
|
val.value.integer = ungetc(chr, fp);
|
||||||
|
if (val.value.integer != EOF) val.value.integer = 0;
|
||||||
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -763,7 +781,7 @@ static PLI_INT32 sys_fseek_compiletf(PLI_BYTE8*name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!arg || !is_numeric_obj(arg)) {
|
if (! is_numeric_obj(arg)) {
|
||||||
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's second argument must be numeric.\n", name);
|
vpi_printf("%s's second argument must be numeric.\n", name);
|
||||||
|
|
@ -780,7 +798,7 @@ static PLI_INT32 sys_fseek_compiletf(PLI_BYTE8*name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!arg || !is_numeric_obj(arg)) {
|
if (! is_numeric_obj(arg)) {
|
||||||
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's third argument must be numeric.\n", name);
|
vpi_printf("%s's third argument must be numeric.\n", name);
|
||||||
|
|
@ -802,7 +820,7 @@ static PLI_INT32 sys_fseek_calltf(PLI_BYTE8*name)
|
||||||
PLI_UINT32 fd_mcd;
|
PLI_UINT32 fd_mcd;
|
||||||
PLI_INT32 offset, oper;
|
PLI_INT32 offset, oper;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
/* Get the file pointer. */
|
/* Get the file pointer. */
|
||||||
arg = vpi_scan(argv);
|
arg = vpi_scan(argv);
|
||||||
|
|
@ -824,15 +842,22 @@ static PLI_INT32 sys_fseek_calltf(PLI_BYTE8*name)
|
||||||
oper = val.value.integer;
|
oper = val.value.integer;
|
||||||
|
|
||||||
/* Check that the operation is in the valid range. */
|
/* Check that the operation is in the valid range. */
|
||||||
if ((oper < 0) || (oper > 2)) {
|
switch (oper) {
|
||||||
|
case 0:
|
||||||
|
oper = SEEK_SET;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
oper = SEEK_CUR;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
oper = SEEK_END;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's operation must be 0, 1 or 2 given %d.\n",
|
vpi_printf("%s's operation must be 0, 1 or 2 given %d.\n",
|
||||||
name, oper);
|
name, oper);
|
||||||
val.format = vpiIntVal;
|
oper = -1; /* An invalid argument value. */
|
||||||
val.value.integer = EOF;
|
|
||||||
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return EOF if this is not a valid fd. */
|
/* Return EOF if this is not a valid fd. */
|
||||||
|
|
@ -842,6 +867,7 @@ static PLI_INT32 sys_fseek_calltf(PLI_BYTE8*name)
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
||||||
name);
|
name);
|
||||||
|
errno = EBADF;
|
||||||
val.format = vpiIntVal;
|
val.format = vpiIntVal;
|
||||||
val.value.integer = EOF;
|
val.value.integer = EOF;
|
||||||
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
||||||
|
|
@ -863,6 +889,7 @@ static PLI_INT32 sys_common_fd_calltf(PLI_BYTE8*name)
|
||||||
s_vpi_value val;
|
s_vpi_value val;
|
||||||
PLI_UINT32 fd_mcd;
|
PLI_UINT32 fd_mcd;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
/* Get the file pointer. */
|
/* Get the file pointer. */
|
||||||
arg = vpi_scan(argv);
|
arg = vpi_scan(argv);
|
||||||
|
|
@ -878,6 +905,7 @@ static PLI_INT32 sys_common_fd_calltf(PLI_BYTE8*name)
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
||||||
name);
|
name);
|
||||||
|
errno = EBADF;
|
||||||
val.format = vpiIntVal;
|
val.format = vpiIntVal;
|
||||||
val.value.integer = EOF;
|
val.value.integer = EOF;
|
||||||
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
||||||
|
|
@ -910,6 +938,119 @@ static PLI_INT32 sys_common_fd_calltf(PLI_BYTE8*name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implement the $ferror system function.
|
||||||
|
*/
|
||||||
|
static PLI_INT32 sys_ferror_compiletf(PLI_BYTE8 *name)
|
||||||
|
{
|
||||||
|
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||||
|
vpiHandle argv;
|
||||||
|
vpiHandle arg;
|
||||||
|
|
||||||
|
argv = vpi_iterate(vpiArgument, callh);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that there are two arguments and that the first is
|
||||||
|
* numeric and that the second is a 640 bit or larger register.
|
||||||
|
*
|
||||||
|
* The parser requires that a function have at least one argument,
|
||||||
|
* so argv should always be defined with one argument.
|
||||||
|
*/
|
||||||
|
assert(argv);
|
||||||
|
|
||||||
|
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 fd (first) argument must be numeric.\n", name);
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that the second argument is given and that it is a 640 bit
|
||||||
|
* or larger register. */
|
||||||
|
arg = vpi_scan(argv);
|
||||||
|
if (! arg) {
|
||||||
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_printf("%s requires a second (register) argument.\n", name);
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vpi_get(vpiType, arg) != vpiReg) {
|
||||||
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_printf("%s's second argument must be a reg (>=640 bits).\n",
|
||||||
|
name);
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
} else if (vpi_get(vpiSize, arg) < 640) {
|
||||||
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_printf("%s's second argument must have 640 bit or more.\n",
|
||||||
|
name);
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure there are no extra arguments. */
|
||||||
|
check_for_extra_args(argv, callh, name, "two arguments", 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PLI_INT32 sys_ferror_calltf(PLI_BYTE8 *name)
|
||||||
|
{
|
||||||
|
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||||
|
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||||
|
vpiHandle reg;
|
||||||
|
s_vpi_value val;
|
||||||
|
char *msg;
|
||||||
|
PLI_INT32 size;
|
||||||
|
unsigned chars;
|
||||||
|
PLI_UINT32 fd_mcd;
|
||||||
|
|
||||||
|
/* Get the file pointer. */
|
||||||
|
val.format = vpiIntVal;
|
||||||
|
vpi_get_value(vpi_scan(argv), &val);
|
||||||
|
fd_mcd = val.value.integer;
|
||||||
|
|
||||||
|
/* Get the register to put the string result and figure out how many
|
||||||
|
* characters it will hold. */
|
||||||
|
reg = vpi_scan(argv);
|
||||||
|
size = vpi_get(vpiSize, reg);
|
||||||
|
chars = size / 8;
|
||||||
|
vpi_free_object(argv);
|
||||||
|
|
||||||
|
/* If we do not already have an error check that the fd is valid.
|
||||||
|
* The assumption is that the other routines have set errno to
|
||||||
|
* EBADF when they encounter a bad file descriptor, so we do not
|
||||||
|
* need to check here. We also need to special case this since
|
||||||
|
* $fopen() will return 0 (a bad file descriptor) when it has a
|
||||||
|
* problem (sets errno). */
|
||||||
|
if (!errno && !vpi_get_file(fd_mcd) ) {
|
||||||
|
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
||||||
|
name);
|
||||||
|
errno = EBADF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the error code. */
|
||||||
|
val.format = vpiIntVal;
|
||||||
|
val.value.integer = errno;
|
||||||
|
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
||||||
|
|
||||||
|
/* Only return the number of characters that will fit in the reg. */
|
||||||
|
msg = (char *) malloc(chars);
|
||||||
|
if (errno != 0) strncpy(msg, strerror(errno), chars-1);
|
||||||
|
else strncpy(msg, "", chars-1);
|
||||||
|
msg[chars-1] = '\0';
|
||||||
|
val.format = vpiStringVal;
|
||||||
|
val.value.str = msg;
|
||||||
|
vpi_put_value(reg, &val, 0, vpiNoDelay);
|
||||||
|
free(msg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void sys_fileio_register()
|
void sys_fileio_register()
|
||||||
{
|
{
|
||||||
s_vpi_systf_data tf_data;
|
s_vpi_systf_data tf_data;
|
||||||
|
|
@ -962,15 +1103,6 @@ void sys_fileio_register()
|
||||||
tf_data.user_data = "$fflush";
|
tf_data.user_data = "$fflush";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
||||||
/*============================== fputc */
|
|
||||||
tf_data.type = vpiSysTask;
|
|
||||||
tf_data.tfname = "$fputc";
|
|
||||||
tf_data.calltf = sys_fputc_calltf;
|
|
||||||
tf_data.compiletf = sys_two_numeric_args_compiletf;
|
|
||||||
tf_data.sizetf = 0;
|
|
||||||
tf_data.user_data = "$fputc";
|
|
||||||
vpi_register_systf(&tf_data);
|
|
||||||
|
|
||||||
/*============================== fgetc */
|
/*============================== fgetc */
|
||||||
tf_data.type = vpiSysFunc;
|
tf_data.type = vpiSysFunc;
|
||||||
tf_data.sysfunctype = vpiIntFunc;
|
tf_data.sysfunctype = vpiIntFunc;
|
||||||
|
|
@ -1041,7 +1173,17 @@ void sys_fileio_register()
|
||||||
tf_data.user_data = "$rewind";
|
tf_data.user_data = "$rewind";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
||||||
/* $feof() is from 1364-2005. */
|
/*============================== ferror */
|
||||||
|
tf_data.type = vpiSysFunc;
|
||||||
|
tf_data.sysfunctype = vpiIntFunc;
|
||||||
|
tf_data.tfname = "$ferror";
|
||||||
|
tf_data.calltf = sys_ferror_calltf;
|
||||||
|
tf_data.compiletf = sys_ferror_compiletf;
|
||||||
|
tf_data.sizetf = 0;
|
||||||
|
tf_data.user_data = "$ferror";
|
||||||
|
vpi_register_systf(&tf_data);
|
||||||
|
|
||||||
|
/* $feof() is from 1364-2005. */
|
||||||
/*============================== feof */
|
/*============================== feof */
|
||||||
tf_data.type = vpiSysFunc;
|
tf_data.type = vpiSysFunc;
|
||||||
tf_data.sysfunctype = vpiIntFunc;
|
tf_data.sysfunctype = vpiIntFunc;
|
||||||
|
|
@ -1052,4 +1194,14 @@ void sys_fileio_register()
|
||||||
tf_data.user_data = "$feof";
|
tf_data.user_data = "$feof";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
||||||
|
/* Icarus specific. */
|
||||||
|
/*============================== fputc */
|
||||||
|
tf_data.type = vpiSysFunc;
|
||||||
|
tf_data.sysfunctype = vpiIntFunc;
|
||||||
|
tf_data.tfname = "$fputc";
|
||||||
|
tf_data.calltf = sys_fputc_calltf;
|
||||||
|
tf_data.compiletf = sys_two_numeric_args_compiletf;
|
||||||
|
tf_data.sizetf = 0;
|
||||||
|
tf_data.user_data = "$fputc";
|
||||||
|
vpi_register_systf(&tf_data);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,17 +53,6 @@ static PLI_INT32 task_not_implemented_compiletf(PLI_BYTE8* name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PLI_INT32 function_not_implemented_compiletf(PLI_BYTE8* name)
|
|
||||||
{
|
|
||||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
|
||||||
|
|
||||||
vpi_printf("%s:%d: SORRY: function %s() is not currently implemented.\n",
|
|
||||||
vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh),
|
|
||||||
name);
|
|
||||||
vpi_control(vpiFinish, 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is used to warn the user that the specified optional system
|
* This is used to warn the user that the specified optional system
|
||||||
* task/function is not available (from Annex C 1364-2005).
|
* task/function is not available (from Annex C 1364-2005).
|
||||||
|
|
@ -222,15 +211,6 @@ void sys_special_register(void)
|
||||||
|
|
||||||
tf_data.tfname = "$dumpportsflush";
|
tf_data.tfname = "$dumpportsflush";
|
||||||
tf_data.user_data = "$dumpportsflush";
|
tf_data.user_data = "$dumpportsflush";
|
||||||
vpi_register_systf(&tf_data);
|
|
||||||
|
|
||||||
/* These functions are not currently implemented. */
|
|
||||||
tf_data.compiletf = function_not_implemented_compiletf;
|
|
||||||
tf_data.type = vpiSysFunc;
|
|
||||||
tf_data.sysfunctype = vpiIntFunc;
|
|
||||||
|
|
||||||
tf_data.tfname = "$ferror";
|
|
||||||
tf_data.user_data = "$ferror";
|
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
||||||
/* The following optional system tasks/functions are not implemented
|
/* The following optional system tasks/functions are not implemented
|
||||||
|
|
|
||||||
|
|
@ -440,10 +440,24 @@ static void *close_dumpfile(void)
|
||||||
|
|
||||||
static void open_dumpfile(vpiHandle callh)
|
static void open_dumpfile(vpiHandle callh)
|
||||||
{
|
{
|
||||||
|
off_t use_file_size_limit = lxt2_file_size_limit;
|
||||||
if (dump_path == 0) dump_path = strdup("dump.lx2");
|
if (dump_path == 0) dump_path = strdup("dump.lx2");
|
||||||
|
|
||||||
dump_file = lxt2_wr_init(dump_path);
|
dump_file = lxt2_wr_init(dump_path);
|
||||||
|
|
||||||
|
if (getenv("LXT_FILE_SIZE_LIMIT")) {
|
||||||
|
const char*limit_string = getenv("LXT_FILE_SIZE_LIMIT");
|
||||||
|
char*ep;
|
||||||
|
use_file_size_limit = strtoul(limit_string,&ep,0);
|
||||||
|
if (use_file_size_limit == 0 || ep[0] != 0) {
|
||||||
|
vpi_printf("LXT2 Warning: %s:%d: LXT_FILE_SIZE_LIMIT is invalid: %s\n",
|
||||||
|
vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh),
|
||||||
|
limit_string);
|
||||||
|
use_file_size_limit = lxt2_file_size_limit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (dump_file == 0) {
|
if (dump_file == 0) {
|
||||||
vpi_printf("LXT2 Error: %s:%d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("LXT2 Error: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
|
@ -462,7 +476,7 @@ static void open_dumpfile(vpiHandle callh)
|
||||||
lxt2_wr_set_initial_value(dump_file, 'x');
|
lxt2_wr_set_initial_value(dump_file, 'x');
|
||||||
lxt2_wr_set_compression_depth(dump_file, 4);
|
lxt2_wr_set_compression_depth(dump_file, 4);
|
||||||
lxt2_wr_set_partial_on(dump_file, 1);
|
lxt2_wr_set_partial_on(dump_file, 1);
|
||||||
lxt2_wr_set_break_size(dump_file, lxt2_file_size_limit);
|
lxt2_wr_set_break_size(dump_file, use_file_size_limit);
|
||||||
|
|
||||||
atexit((void(*)(void))close_dumpfile);
|
atexit((void(*)(void))close_dumpfile);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -401,7 +401,7 @@ static PLI_INT32 sys_readmem_calltf(PLI_BYTE8*name)
|
||||||
free(value.value.vector);
|
free(value.value.vector);
|
||||||
free(fname);
|
free(fname);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
destroy_readmem_lexor(file);
|
destroy_readmem_lexor();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
# include "vpi_user.h"
|
# include "vpi_user.h"
|
||||||
# include "sys_priv.h"
|
# include "sys_priv.h"
|
||||||
# include <ctype.h>
|
# include <ctype.h>
|
||||||
|
# include <errno.h>
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
|
|
@ -639,6 +640,7 @@ static PLI_INT32 sys_fscanf_calltf(PLI_BYTE8*name)
|
||||||
s_vpi_value val;
|
s_vpi_value val;
|
||||||
struct byte_source src;
|
struct byte_source src;
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
val.format = vpiIntVal;
|
val.format = vpiIntVal;
|
||||||
vpi_get_value(vpi_scan(argv), &val);
|
vpi_get_value(vpi_scan(argv), &val);
|
||||||
|
|
@ -648,9 +650,11 @@ static PLI_INT32 sys_fscanf_calltf(PLI_BYTE8*name)
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("invalid file descriptor (0x%x) given to %s.\n",
|
vpi_printf("invalid file descriptor (0x%x) given to %s.\n",
|
||||||
val.value.integer, name);
|
val.value.integer, name);
|
||||||
|
errno = EBADF;
|
||||||
val.format = vpiIntVal;
|
val.format = vpiIntVal;
|
||||||
val.value.integer = EOF;
|
val.value.integer = EOF;
|
||||||
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
||||||
|
vpi_free_object(argv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -258,7 +258,10 @@ extern "C" PLI_INT32 vpi_fopen(const char*name, const char*mode)
|
||||||
}
|
}
|
||||||
/* We need to allocate more table entries, but to keep things */
|
/* We need to allocate more table entries, but to keep things */
|
||||||
/* sane we'll hard limit this to 1024 file descriptors total. */
|
/* sane we'll hard limit this to 1024 file descriptors total. */
|
||||||
if (fd_table_len >= 1024) return 0;
|
if (fd_table_len >= 1024) {
|
||||||
|
vpi_printf("WARNING: Icarus only supports 1024 open files!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
fd_table_len += FD_INCR;
|
fd_table_len += FD_INCR;
|
||||||
fd_table = (mcd_entry_s *) realloc(fd_table,
|
fd_table = (mcd_entry_s *) realloc(fd_table,
|
||||||
fd_table_len*sizeof(mcd_entry_s));
|
fd_table_len*sizeof(mcd_entry_s));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue