Update FST files to latest from GTKWave
This commit is contained in:
parent
0509bdd53e
commit
9b38de596e
281
vpi/fstapi.c
281
vpi/fstapi.c
|
|
@ -33,24 +33,41 @@
|
|||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
/* this define is to force writer backward compatibility with old readers */
|
||||
#ifndef FST_DYNAMIC_ALIAS_DISABLE
|
||||
#if HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#elif defined(__GNUC__)
|
||||
#ifndef __MINGW32__
|
||||
#ifndef alloca
|
||||
#define alloca __builtin_alloca
|
||||
#endif
|
||||
#else
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#elif defined(_MSC_VER)
|
||||
#include <malloc.h>
|
||||
#define alloca _alloca
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX (4096)
|
||||
#endif
|
||||
|
||||
/* note that Judy versus Jenkins requires more experimentation: they are */
|
||||
/* functionally equivalent though it appears Jenkins is slightly faster. */
|
||||
/* in addition, Jenkins is not bound by the LGPL. */
|
||||
#ifdef _WAVE_HAVE_JUDY
|
||||
#include <Judy.h>
|
||||
#else
|
||||
/* should be more than enough for fstWriterSetSourceStem() */
|
||||
#define FST_PATH_HASHMASK ((1UL << 16) - 1)
|
||||
typedef const void *Pcvoid_t;
|
||||
typedef void *Pvoid_t;
|
||||
typedef void **PPvoid_t;
|
||||
#define JudyHSIns(a,b,c,d) JenkinsIns((a),(b),(c),(hashmask))
|
||||
#define JudyHSFreeArray(a,b) JenkinsFree((a),(hashmask))
|
||||
void JenkinsFree(void *base_i, uint32_t hashmask);
|
||||
void **JenkinsIns(void *base_i, unsigned char *mem, uint32_t length, uint32_t hashmask);
|
||||
void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint32_t hashmask);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#undef FST_DEBUG
|
||||
|
||||
|
|
@ -65,7 +82,9 @@ void **JenkinsIns(void *base_i, unsigned char *mem, uint32_t length, uint32_t ha
|
|||
#define FST_ID_NAM_ATTR_SIZ (65536+4096)
|
||||
#define FST_DOUBLE_ENDTEST (2.7182818284590452354)
|
||||
#define FST_HDR_SIM_VERSION_SIZE (128)
|
||||
#define FST_HDR_DATE_SIZE (120)
|
||||
#define FST_HDR_DATE_SIZE (119)
|
||||
#define FST_HDR_FILETYPE_SIZE (1)
|
||||
#define FST_HDR_TIMEZERO_SIZE (8)
|
||||
#define FST_GZIO_LEN (32768)
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(_AIX)
|
||||
|
|
@ -135,6 +154,36 @@ return(ftruncate(fd, length));
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* realpath compatibility
|
||||
*/
|
||||
static char *fstRealpath(const char *path, char *resolved_path)
|
||||
{
|
||||
#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __CYGWIN__ || defined HAVE_REALPATH
|
||||
|
||||
#if (defined(__MACH__) && defined(__APPLE__))
|
||||
if(!resolved_path)
|
||||
{
|
||||
resolved_path = malloc(PATH_MAX+1); /* fixes bug on Leopard when resolved_path == NULL */
|
||||
}
|
||||
#endif
|
||||
|
||||
return(realpath(path, resolved_path));
|
||||
|
||||
#else
|
||||
#ifdef __MINGW32__
|
||||
if(!resolved_path)
|
||||
{
|
||||
resolved_path = malloc(PATH_MAX+1);
|
||||
}
|
||||
return(_fullpath(resolved_path, path, PATH_MAX));
|
||||
#else
|
||||
return(NULL);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mmap compatibility
|
||||
*/
|
||||
|
|
@ -304,6 +353,21 @@ do {
|
|||
|
||||
return(pnt);
|
||||
}
|
||||
|
||||
|
||||
static unsigned char *fstCopyVarint64ToRight(unsigned char *pnt, uint64_t v)
|
||||
{
|
||||
uint64_t nxt;
|
||||
|
||||
while((nxt = v>>7))
|
||||
{
|
||||
*(pnt++) = (v&0x7f) | 0x80;
|
||||
v = nxt;
|
||||
}
|
||||
*(pnt++) = (v&0x7f);
|
||||
|
||||
return(pnt);
|
||||
}
|
||||
|
||||
|
||||
static uint64_t fstGetVarint64(unsigned char *mem, int *skiplen)
|
||||
|
|
@ -490,7 +554,6 @@ uint64_t firsttime;
|
|||
uint32_t vchg_siz;
|
||||
uint32_t vchg_alloc_siz;
|
||||
|
||||
|
||||
uint32_t secnum;
|
||||
off_t section_start;
|
||||
|
||||
|
|
@ -503,6 +566,8 @@ uint32_t num_blackouts;
|
|||
|
||||
uint64_t dump_size_limit;
|
||||
|
||||
unsigned char filetype; /* default is 0, FST_FT_VERILOG */
|
||||
|
||||
unsigned compress_hier : 1;
|
||||
unsigned repack_on_close : 1;
|
||||
unsigned skip_writing_section_hdr : 1;
|
||||
|
|
@ -533,6 +598,9 @@ size_t fst_huge_break_size;
|
|||
|
||||
fstHandle next_huge_break;
|
||||
|
||||
Pvoid_t path_array;
|
||||
uint32_t path_array_count;
|
||||
|
||||
unsigned fseek_failed : 1;
|
||||
};
|
||||
|
||||
|
|
@ -672,12 +740,15 @@ time(&walltime);
|
|||
strcpy(dbuf, asctime(localtime(&walltime)));
|
||||
fstFwrite(dbuf, FST_HDR_DATE_SIZE, 1, xc->handle); /* +202 date */
|
||||
|
||||
/* date size is deliberately overspecified at 120 bytes in order to provide backfill for new args */
|
||||
/* date size is deliberately overspecified at 119 bytes (originally 128) in order to provide backfill for new args */
|
||||
|
||||
#define FST_HDR_OFFS_TIMEZERO (FST_HDR_OFFS_DATE + FST_HDR_DATE_SIZE)
|
||||
#define FST_HDR_OFFS_FILETYPE (FST_HDR_OFFS_DATE + FST_HDR_DATE_SIZE)
|
||||
fputc(xc->filetype, xc->handle); /* +321 filetype */
|
||||
|
||||
#define FST_HDR_OFFS_TIMEZERO (FST_HDR_OFFS_FILETYPE + FST_HDR_FILETYPE_SIZE)
|
||||
fstWriterUint64(xc->handle, xc->timezero); /* +322 timezero */
|
||||
|
||||
#define FST_HDR_LENGTH (FST_HDR_OFFS_TIMEZERO + 8)
|
||||
#define FST_HDR_LENGTH (FST_HDR_OFFS_TIMEZERO + FST_HDR_TIMEZERO_SIZE)
|
||||
/* +330 next section starts here */
|
||||
fflush(xc->handle);
|
||||
}
|
||||
|
|
@ -1796,6 +1867,14 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
|
|||
pthread_attr_destroy(&xc->thread_attr);
|
||||
#endif
|
||||
|
||||
if(xc->path_array)
|
||||
{
|
||||
#ifndef _WAVE_HAVE_JUDY
|
||||
const uint32_t hashmask = FST_PATH_HASHMASK;
|
||||
#endif
|
||||
JudyHSFreeArray(&(xc->path_array), NULL);
|
||||
}
|
||||
|
||||
free(xc->filename); xc->filename = NULL;
|
||||
free(xc);
|
||||
}
|
||||
|
|
@ -1843,7 +1922,44 @@ if(xc && vers)
|
|||
}
|
||||
|
||||
|
||||
static void fstWriterSetAttrGeneric(void *ctx, const char *comm, int typ)
|
||||
void fstWriterSetFileType(void *ctx, enum fstFileType filetype)
|
||||
{
|
||||
struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
|
||||
if(xc)
|
||||
{
|
||||
if((filetype >= FST_FT_MIN) && (filetype <= FST_FT_MAX))
|
||||
{
|
||||
off_t fpos = ftello(xc->handle);
|
||||
|
||||
xc->filetype = filetype;
|
||||
|
||||
fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_FILETYPE, SEEK_SET);
|
||||
fputc(xc->filetype, xc->handle);
|
||||
fflush(xc->handle);
|
||||
fstWriterFseeko(xc, xc->handle, fpos, SEEK_SET);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void fstWriterSetAttrDoubleArgGeneric(void *ctx, int typ, uint64_t arg1, uint64_t arg2)
|
||||
{
|
||||
struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
|
||||
if(xc)
|
||||
{
|
||||
unsigned char buf[11]; /* ceil(64/7) = 10 + null term */
|
||||
unsigned char *pnt = fstCopyVarint64ToRight(buf, arg1);
|
||||
if(arg1)
|
||||
{
|
||||
*pnt = 0; /* this converts any *nonzero* arg1 when made a varint into a null-term string */
|
||||
}
|
||||
|
||||
fstWriterSetAttrBegin(xc, FST_AT_MISC, typ, (char *)buf, arg2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void fstWriterSetAttrGeneric(void *ctx, const char *comm, int typ, uint64_t arg)
|
||||
{
|
||||
struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
|
||||
if(xc && comm)
|
||||
|
|
@ -1857,21 +1973,87 @@ if(xc && comm)
|
|||
s++;
|
||||
}
|
||||
|
||||
fstWriterSetAttrBegin(xc, FST_AT_MISC, typ, sf, 0);
|
||||
fstWriterSetAttrBegin(xc, FST_AT_MISC, typ, sf, arg);
|
||||
free(sf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void fstWriterSetSourceStem_2(void *ctx, const char *path, unsigned int line, unsigned int use_realpath, int typ)
|
||||
{
|
||||
struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
|
||||
|
||||
if(xc && path && path[0])
|
||||
{
|
||||
uint64_t sidx = 0;
|
||||
int slen = strlen(path);
|
||||
#ifndef _WAVE_HAVE_JUDY
|
||||
const uint32_t hashmask = FST_PATH_HASHMASK;
|
||||
const unsigned char *path2 = (const unsigned char *)path;
|
||||
#else
|
||||
char *path2 = alloca(slen + 1); /* judy lacks const qualifier in its JudyHSIns definition */
|
||||
strcpy(path2, path);
|
||||
#endif
|
||||
|
||||
PPvoid_t pv = JudyHSIns(&(xc->path_array), path2, slen, NULL);
|
||||
if(*pv)
|
||||
{
|
||||
sidx = (long)(*pv);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *rp = NULL;
|
||||
|
||||
sidx = ++xc->path_array_count;
|
||||
*pv = (void *)(long)(xc->path_array_count);
|
||||
|
||||
if(use_realpath)
|
||||
{
|
||||
rp = fstRealpath(
|
||||
#ifndef _WAVE_HAVE_JUDY
|
||||
(const char *)
|
||||
#endif
|
||||
path2, NULL);
|
||||
}
|
||||
|
||||
fstWriterSetAttrGeneric(xc, rp ? rp :
|
||||
#ifndef _WAVE_HAVE_JUDY
|
||||
(const char *)
|
||||
#endif
|
||||
path2, FST_MT_PATHNAME, sidx);
|
||||
|
||||
if(rp)
|
||||
{
|
||||
free(rp);
|
||||
}
|
||||
}
|
||||
|
||||
fstWriterSetAttrDoubleArgGeneric(xc, typ, sidx, line);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void fstWriterSetSourceStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath)
|
||||
{
|
||||
fstWriterSetSourceStem_2(ctx, path, line, use_realpath, FST_MT_SOURCESTEM);
|
||||
}
|
||||
|
||||
|
||||
void fstWriterSetSourceInstantiationStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath)
|
||||
{
|
||||
fstWriterSetSourceStem_2(ctx, path, line, use_realpath, FST_MT_SOURCEISTEM);
|
||||
}
|
||||
|
||||
|
||||
void fstWriterSetComment(void *ctx, const char *comm)
|
||||
{
|
||||
fstWriterSetAttrGeneric(ctx, comm, FST_MT_COMMENT);
|
||||
fstWriterSetAttrGeneric(ctx, comm, FST_MT_COMMENT, 0);
|
||||
}
|
||||
|
||||
|
||||
void fstWriterSetEnvVar(void *ctx, const char *envvar)
|
||||
{
|
||||
fstWriterSetAttrGeneric(ctx, envvar, FST_MT_ENVVAR);
|
||||
fstWriterSetAttrGeneric(ctx, envvar, FST_MT_ENVVAR, 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1903,14 +2085,14 @@ if(xc && s)
|
|||
{
|
||||
switch(*pnt)
|
||||
{
|
||||
case 'm': seconds_exp = -3; mat = 1; break;
|
||||
case 'u': seconds_exp = -6; mat = 1; break;
|
||||
case 'n': seconds_exp = -9; mat = 1; break;
|
||||
case 'm': seconds_exp = -3; mat = 1; break;
|
||||
case 'u': seconds_exp = -6; mat = 1; break;
|
||||
case 'n': seconds_exp = -9; mat = 1; break;
|
||||
case 'p': seconds_exp = -12; mat = 1; break;
|
||||
case 'f': seconds_exp = -15; mat = 1; break;
|
||||
case 'a': seconds_exp = -18; mat = 1; break;
|
||||
case 'z': seconds_exp = -21; mat = 1; break;
|
||||
case 's': seconds_exp = -0; mat = 1; break;
|
||||
case 's': seconds_exp = 0; mat = 1; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
|
@ -2020,8 +2202,19 @@ return(0);
|
|||
|
||||
|
||||
/*
|
||||
* writer attr/scope/var creation
|
||||
* writer attr/scope/var creation:
|
||||
* fstWriterCreateVar2() is used to dump VHDL or other languages, but the
|
||||
* underlying variable needs to map to Verilog/SV via the proper fstVarType vt
|
||||
*/
|
||||
fstHandle fstWriterCreateVar2(void *ctx, enum fstVarType vt, enum fstVarDir vd,
|
||||
uint32_t len, const char *nam, fstHandle aliasHandle,
|
||||
const char *type, enum fstSupplementalVarType svt, enum fstSupplementalDataType sdt)
|
||||
{
|
||||
fstWriterSetAttrGeneric(ctx, type ? type : "", FST_MT_SUPVAR, (svt<<FST_SDT_SVT_SHIFT_COUNT) | (sdt & FST_SDT_ABS_MAX));
|
||||
return(fstWriterCreateVar(ctx, vt, vd, len, nam, aliasHandle));
|
||||
}
|
||||
|
||||
|
||||
fstHandle fstWriterCreateVar(void *ctx, enum fstVarType vt, enum fstVarDir vd,
|
||||
uint32_t len, const char *nam, fstHandle aliasHandle)
|
||||
{
|
||||
|
|
@ -2474,7 +2667,8 @@ static const char *vartypes[] = {
|
|||
};
|
||||
|
||||
static const char *modtypes[] = {
|
||||
"module", "task", "function", "begin", "fork", "generate", "struct", "union", "class", "interface", "package", "program"
|
||||
"module", "task", "function", "begin", "fork", "generate", "struct", "union", "class", "interface", "package", "program",
|
||||
"vhdl_architecture", "vhdl_procedure", "vhdl_function", "vhdl_record", "vhdl_process", "vhdl_block", "vhdl_for_generate", "vhdl_if_generate", "vhdl_generate", "vhdl_package"
|
||||
};
|
||||
|
||||
static const char *attrtypes[] = {
|
||||
|
|
@ -2524,6 +2718,8 @@ uint32_t longest_signal_value_len; /* longest len value encountered */
|
|||
unsigned char *temp_signal_value_buf; /* malloced for len in longest_signal_value_len */
|
||||
|
||||
signed char timescale;
|
||||
unsigned char filetype;
|
||||
|
||||
unsigned double_endian_match : 1;
|
||||
unsigned native_doubles_for_cb : 1;
|
||||
unsigned contains_geom_section : 1;
|
||||
|
|
@ -2902,6 +3098,14 @@ struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
|
|||
return(xc ? xc->date : NULL);
|
||||
}
|
||||
|
||||
|
||||
int fstReaderGetFileType(void *ctx)
|
||||
{
|
||||
struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
|
||||
return(xc ? xc->filetype : FST_FT_VERILOG);
|
||||
}
|
||||
|
||||
|
||||
int64_t fstReaderGetTimezero(void *ctx)
|
||||
{
|
||||
struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
|
||||
|
|
@ -3196,6 +3400,15 @@ if(!(isfeof=feof(xc->fh)))
|
|||
xc->hier.u.attr.name_length = pnt - xc->hier.u.scope.name;
|
||||
|
||||
xc->hier.u.attr.arg = fstReaderVarint64(xc->fh);
|
||||
|
||||
if(xc->hier.u.attr.typ == FST_AT_MISC)
|
||||
{
|
||||
if((xc->hier.u.attr.subtype == FST_MT_SOURCESTEM)||(xc->hier.u.attr.subtype == FST_MT_SOURCEISTEM))
|
||||
{
|
||||
int sidx_skiplen_dummy = 0;
|
||||
xc->hier.u.attr.arg_from_name = fstGetVarint64((unsigned char *)xc->str_scope_nam, &sidx_skiplen_dummy);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FST_ST_GEN_ATTREND:
|
||||
|
|
@ -3233,7 +3446,9 @@ if(!(isfeof=feof(xc->fh)))
|
|||
case FST_VT_SV_ENUM:
|
||||
case FST_VT_SV_SHORTREAL:
|
||||
xc->hier.htyp = FST_HT_VAR;
|
||||
|
||||
xc->hier.u.var.svt_workspace = FST_SVT_NONE;
|
||||
xc->hier.u.var.sdt_workspace = FST_SDT_NONE;
|
||||
xc->hier.u.var.sxt_workspace = 0;
|
||||
xc->hier.u.var.typ = tag;
|
||||
xc->hier.u.var.direction = fgetc(xc->fh);
|
||||
xc->hier.u.var.name = pnt = xc->str_scope_nam;
|
||||
|
|
@ -3368,7 +3583,7 @@ while(!feof(xc->fh))
|
|||
{
|
||||
case FST_ST_VCD_SCOPE:
|
||||
scopetype = fgetc(xc->fh);
|
||||
if((scopetype < FST_ST_VCD_MIN) || (scopetype > FST_ST_MAX)) scopetype = FST_ST_VCD_MODULE;
|
||||
if((scopetype < FST_ST_MIN) || (scopetype > FST_ST_MAX)) scopetype = FST_ST_VCD_MODULE;
|
||||
pnt = str;
|
||||
while((ch = fgetc(xc->fh)))
|
||||
{
|
||||
|
|
@ -3394,6 +3609,8 @@ while(!feof(xc->fh))
|
|||
}; /* attrname */
|
||||
*pnt = 0;
|
||||
|
||||
if(!str[0]) { strcpy(str, "\"\""); }
|
||||
|
||||
attrarg = fstReaderVarint64(xc->fh);
|
||||
|
||||
if(fv)
|
||||
|
|
@ -3417,7 +3634,17 @@ while(!feof(xc->fh))
|
|||
}
|
||||
else
|
||||
{
|
||||
fprintf(fv, "$attrbegin %s %02x %s %"PRId64" $end\n", attrtypes[attrtype], subtype, str, attrarg);
|
||||
if((subtype == FST_MT_SOURCESTEM)||(subtype == FST_MT_SOURCEISTEM))
|
||||
{
|
||||
int sidx_skiplen_dummy = 0;
|
||||
uint64_t sidx = fstGetVarint64((unsigned char *)str, &sidx_skiplen_dummy);
|
||||
|
||||
fprintf(fv, "$attrbegin %s %02x %"PRId64" %"PRId64" $end\n", attrtypes[attrtype], subtype, sidx, attrarg);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(fv, "$attrbegin %s %02x %s %"PRId64" $end\n", attrtypes[attrtype], subtype, str, attrarg);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -3705,6 +3932,8 @@ if(gzread_pass_status)
|
|||
xc->version[FST_HDR_SIM_VERSION_SIZE] = 0;
|
||||
fstFread(xc->date, FST_HDR_DATE_SIZE, 1, xc->f);
|
||||
xc->date[FST_HDR_DATE_SIZE] = 0;
|
||||
ch = fgetc(xc->f);
|
||||
xc->filetype = (unsigned char)ch;
|
||||
xc->timezero = fstReaderUint64(xc->f);
|
||||
}
|
||||
}
|
||||
|
|
@ -4004,6 +4233,8 @@ scatterptr = calloc(xc->maxhandle, sizeof(uint32_t));
|
|||
headptr = calloc(xc->maxhandle, sizeof(uint32_t));
|
||||
length_remaining = calloc(xc->maxhandle, sizeof(uint32_t));
|
||||
|
||||
if(fv) { fprintf(fv, "$dumpvars\n"); }
|
||||
|
||||
for(;;)
|
||||
{
|
||||
uint32_t *tc_head = NULL;
|
||||
|
|
@ -5492,7 +5723,7 @@ acceptable. Do NOT use for cryptographic purposes.
|
|||
--------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static uint32_t j_hash(uint8_t *k, uint32_t length, uint32_t initval)
|
||||
static uint32_t j_hash(const uint8_t *k, uint32_t length, uint32_t initval)
|
||||
{
|
||||
uint32_t a,b,c,len;
|
||||
|
||||
|
|
@ -5551,7 +5782,7 @@ unsigned char mem[1];
|
|||
};
|
||||
|
||||
|
||||
void **JenkinsIns(void *base_i, unsigned char *mem, uint32_t length, uint32_t hashmask)
|
||||
void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint32_t hashmask)
|
||||
{
|
||||
struct collchain_t ***base = (struct collchain_t ***)base_i;
|
||||
uint32_t hf, h;
|
||||
|
|
|
|||
293
vpi/fstapi.h
293
vpi/fstapi.h
|
|
@ -40,6 +40,16 @@ extern "C" {
|
|||
|
||||
typedef uint32_t fstHandle;
|
||||
|
||||
enum fstFileType {
|
||||
FST_FT_MIN = 0,
|
||||
|
||||
FST_FT_VERILOG = 0,
|
||||
FST_FT_VHDL = 1,
|
||||
FST_FT_VERILOG_VHDL = 2,
|
||||
|
||||
FST_FT_MAX = 2
|
||||
};
|
||||
|
||||
enum fstBlockType {
|
||||
FST_BL_HDR = 0,
|
||||
FST_BL_VCDATA = 1,
|
||||
|
|
@ -53,7 +63,8 @@ enum fstBlockType {
|
|||
};
|
||||
|
||||
enum fstScopeType {
|
||||
FST_ST_VCD_MIN = 0,
|
||||
FST_ST_MIN = 0,
|
||||
|
||||
FST_ST_VCD_MODULE = 0,
|
||||
FST_ST_VCD_TASK = 1,
|
||||
FST_ST_VCD_FUNCTION = 2,
|
||||
|
|
@ -66,9 +77,19 @@ enum fstScopeType {
|
|||
FST_ST_VCD_INTERFACE = 9,
|
||||
FST_ST_VCD_PACKAGE = 10,
|
||||
FST_ST_VCD_PROGRAM = 11,
|
||||
FST_ST_VCD_MAX = 11,
|
||||
|
||||
FST_ST_MAX = 11,
|
||||
FST_ST_VHDL_ARCHITECTURE = 12,
|
||||
FST_ST_VHDL_PROCEDURE = 13,
|
||||
FST_ST_VHDL_FUNCTION = 14,
|
||||
FST_ST_VHDL_RECORD = 15,
|
||||
FST_ST_VHDL_PROCESS = 16,
|
||||
FST_ST_VHDL_BLOCK = 17,
|
||||
FST_ST_VHDL_FOR_GENERATE = 18,
|
||||
FST_ST_VHDL_IF_GENERATE = 19,
|
||||
FST_ST_VHDL_GENERATE = 20,
|
||||
FST_ST_VHDL_PACKAGE = 21,
|
||||
|
||||
FST_ST_MAX = 21,
|
||||
|
||||
FST_ST_GEN_ATTRBEGIN = 252,
|
||||
FST_ST_GEN_ATTREND = 253,
|
||||
|
|
@ -78,7 +99,8 @@ enum fstScopeType {
|
|||
};
|
||||
|
||||
enum fstVarType {
|
||||
FST_VT_VCD_MIN = 0, /* start of VCD datatypes */
|
||||
FST_VT_MIN = 0, /* start of vartypes */
|
||||
|
||||
FST_VT_VCD_EVENT = 0,
|
||||
FST_VT_VCD_INTEGER = 1,
|
||||
FST_VT_VCD_PARAMETER = 2,
|
||||
|
|
@ -105,26 +127,32 @@ enum fstVarType {
|
|||
|
||||
FST_VT_SV_BIT = 22,
|
||||
FST_VT_SV_LOGIC = 23,
|
||||
FST_VT_SV_INT = 24, /* declare as 31:0 */
|
||||
FST_VT_SV_SHORTINT = 25, /* declare as 15:0 */
|
||||
FST_VT_SV_LONGINT = 26, /* declare as 63:0 */
|
||||
FST_VT_SV_BYTE = 27, /* declare as 7:0 */
|
||||
FST_VT_SV_INT = 24, /* declare as size = 32 */
|
||||
FST_VT_SV_SHORTINT = 25, /* declare as size = 16 */
|
||||
FST_VT_SV_LONGINT = 26, /* declare as size = 64 */
|
||||
FST_VT_SV_BYTE = 27, /* declare as size = 8 */
|
||||
FST_VT_SV_ENUM = 28, /* declare as appropriate type range */
|
||||
FST_VT_SV_SHORTREAL = 29, /* declare and emit same as FST_VT_VCD_REAL */
|
||||
FST_VT_SV_SHORTREAL = 29, /* declare and emit same as FST_VT_VCD_REAL (needs to be emitted as double, not a float) */
|
||||
|
||||
FST_VT_VCD_MAX = 29 /* end of VCD datatypes */
|
||||
FST_VT_MAX = 29 /* end of vartypes */
|
||||
};
|
||||
|
||||
enum fstVarDir {
|
||||
FST_VD_MIN = 0,
|
||||
|
||||
FST_VD_IMPLICIT = 0,
|
||||
FST_VD_INPUT = 1,
|
||||
FST_VD_OUTPUT = 2,
|
||||
FST_VD_INOUT = 3,
|
||||
FST_VD_BUFFER = 4,
|
||||
FST_VD_LINKAGE = 5,
|
||||
|
||||
FST_VD_MAX = 3
|
||||
FST_VD_MAX = 5
|
||||
};
|
||||
|
||||
enum fstHierType {
|
||||
FST_HT_MIN = 0,
|
||||
|
||||
FST_HT_SCOPE = 0,
|
||||
FST_HT_UPSCOPE = 1,
|
||||
FST_HT_VAR = 2,
|
||||
|
|
@ -135,7 +163,9 @@ enum fstHierType {
|
|||
};
|
||||
|
||||
enum fstAttrType {
|
||||
FST_AT_MISC = 0,
|
||||
FST_AT_MIN = 0,
|
||||
|
||||
FST_AT_MISC = 0, /* self-contained: does not need matching FST_HT_ATTREND */
|
||||
FST_AT_ARRAY = 1,
|
||||
FST_AT_ENUM = 2,
|
||||
FST_AT_PACK = 3,
|
||||
|
|
@ -144,14 +174,22 @@ enum fstAttrType {
|
|||
};
|
||||
|
||||
enum fstMiscType {
|
||||
FST_MT_COMMENT = 0, /* self-contained: does not need matching FST_HT_ATTREND, use fstWriterSetComment() to emit */
|
||||
FST_MT_ENVVAR = 1, /* self-contained: does not need matching FST_HT_ATTREND, use fstWriterSetEnvVar() to emit */
|
||||
FST_MT_UNKNOWN = 2,
|
||||
FST_MT_MIN = 0,
|
||||
|
||||
FST_MT_MAX = 2
|
||||
FST_MT_COMMENT = 0, /* use fstWriterSetComment() to emit */
|
||||
FST_MT_ENVVAR = 1, /* use fstWriterSetEnvVar() to emit */
|
||||
FST_MT_SUPVAR = 2, /* use fstWriterCreateVar2() to emit */
|
||||
FST_MT_PATHNAME = 3, /* reserved for fstWriterSetSourceStem() string -> number management */
|
||||
FST_MT_SOURCESTEM = 4, /* use fstWriterSetSourceStem() to emit */
|
||||
FST_MT_SOURCEISTEM = 5, /* use fstWriterSetSourceInstantiationStem() to emit */
|
||||
FST_MT_UNKNOWN = 6,
|
||||
|
||||
FST_MT_MAX = 6
|
||||
};
|
||||
|
||||
enum fstArrayType {
|
||||
FST_AR_MIN = 0,
|
||||
|
||||
FST_AR_NONE = 0,
|
||||
FST_AR_UNPACKED = 1,
|
||||
FST_AR_PACKED = 2,
|
||||
|
|
@ -188,6 +226,49 @@ enum fstPackType {
|
|||
FST_PT_MAX = 3
|
||||
};
|
||||
|
||||
enum fstSupplementalVarType {
|
||||
FST_SVT_MIN = 0,
|
||||
|
||||
FST_SVT_NONE = 0,
|
||||
|
||||
FST_SVT_VHDL_SIGNAL = 1,
|
||||
FST_SVT_VHDL_VARIABLE = 2,
|
||||
FST_SVT_VHDL_CONSTANT = 3,
|
||||
FST_SVT_VHDL_FILE = 4,
|
||||
FST_SVT_VHDL_MEMORY = 5,
|
||||
|
||||
FST_SVT_MAX = 5,
|
||||
};
|
||||
|
||||
enum fstSupplementalDataType {
|
||||
FST_SDT_MIN = 0,
|
||||
|
||||
FST_SDT_NONE = 0,
|
||||
|
||||
FST_SDT_VHDL_BOOLEAN = 1,
|
||||
FST_SDT_VHDL_BIT = 2,
|
||||
FST_SDT_VHDL_BIT_VECTOR = 3,
|
||||
FST_SDT_VHDL_STD_ULOGIC = 4,
|
||||
FST_SDT_VHDL_STD_ULOGIC_VECTOR = 5,
|
||||
FST_SDT_VHDL_STD_LOGIC = 6,
|
||||
FST_SDT_VHDL_STD_LOGIC_VECTOR = 7,
|
||||
FST_SDT_VHDL_UNSIGNED = 8,
|
||||
FST_SDT_VHDL_SIGNED = 9,
|
||||
FST_SDT_VHDL_INTEGER = 10,
|
||||
FST_SDT_VHDL_REAL = 11,
|
||||
FST_SDT_VHDL_NATURAL = 12,
|
||||
FST_SDT_VHDL_POSITIVE = 13,
|
||||
FST_SDT_VHDL_TIME = 14,
|
||||
FST_SDT_VHDL_CHARACTER = 15,
|
||||
FST_SDT_VHDL_STRING = 16,
|
||||
|
||||
FST_SDT_MAX = 16,
|
||||
|
||||
FST_SDT_SVT_SHIFT_COUNT = 10, /* FST_SVT_* is ORed in by fstWriterCreateVar2() to the left after shifting FST_SDT_SVT_SHIFT_COUNT */
|
||||
FST_SDT_ABS_MAX = ((1<<(FST_SDT_SVT_SHIFT_COUNT))-1)
|
||||
};
|
||||
|
||||
|
||||
struct fstHier
|
||||
{
|
||||
unsigned char htyp;
|
||||
|
|
@ -195,7 +276,7 @@ unsigned char htyp;
|
|||
union {
|
||||
/* if htyp == FST_HT_SCOPE */
|
||||
struct fstHierScope {
|
||||
unsigned char typ; /* FST_ST_VCD_MODULE ... FST_ST_VCD_PROGRAM */
|
||||
unsigned char typ; /* FST_ST_MIN ... FST_ST_MAX */
|
||||
const char *name;
|
||||
const char *component;
|
||||
uint32_t name_length; /* strlen(u.scope.name) */
|
||||
|
|
@ -204,8 +285,11 @@ union {
|
|||
|
||||
/* if htyp == FST_HT_VAR */
|
||||
struct fstHierVar {
|
||||
unsigned char typ; /* FST_VT_VCD_EVENT ... FST_VT_GEN_STRING */
|
||||
unsigned char direction; /* FST_VD_IMPLICIT ... FST_VD_INOUT */
|
||||
unsigned char typ; /* FST_VT_MIN ... FST_VT_MAX */
|
||||
unsigned char direction; /* FST_VD_MIN ... FST_VD_MAX */
|
||||
unsigned char svt_workspace; /* zeroed out by FST reader, for client code use */
|
||||
unsigned char sdt_workspace; /* zeroed out by FST reader, for client code use */
|
||||
unsigned int sxt_workspace; /* zeroed out by FST reader, for client code use */
|
||||
const char *name;
|
||||
uint32_t length;
|
||||
fstHandle handle;
|
||||
|
|
@ -215,10 +299,11 @@ union {
|
|||
|
||||
/* if htyp == FST_HT_ATTRBEGIN */
|
||||
struct fstHierAttr {
|
||||
unsigned char typ; /* FST_AT_MISC ... FST_AT_PACK */
|
||||
unsigned char typ; /* FST_AT_MIN ... FST_AT_MAX */
|
||||
unsigned char subtype; /* from fstMiscType, fstArrayType, fstEnumValueType, fstPackType */
|
||||
const char *name;
|
||||
uint64_t arg; /* number of array elements, struct members, or some other payload (possibly ignored) */
|
||||
uint64_t arg_from_name; /* for when name is overloaded as a variable-length integer (FST_AT_MISC + FST_MT_SOURCESTEM) */
|
||||
uint32_t name_length; /* strlen(u.attr.name) */
|
||||
} attr;
|
||||
} u;
|
||||
|
|
@ -228,101 +313,101 @@ union {
|
|||
/*
|
||||
* writer functions
|
||||
*/
|
||||
fstHandle fstWriterCreateVar(void *ctx, enum fstVarType vt, enum fstVarDir vd,
|
||||
uint32_t len, const char *nam, fstHandle aliasHandle);
|
||||
void fstWriterClose(void *ctx);
|
||||
void * fstWriterCreate(const char *nam, int use_compressed_hier);
|
||||
/* used for Verilog/SV */
|
||||
fstHandle fstWriterCreateVar(void *ctx, enum fstVarType vt, enum fstVarDir vd,
|
||||
uint32_t len, const char *nam, fstHandle aliasHandle);
|
||||
/* future expansion for VHDL and other languages. The variable type, data type, etc map onto
|
||||
the current Verilog/SV one. The "type" string is optional for a more verbose or custom description */
|
||||
fstHandle fstWriterCreateVar2(void *ctx, enum fstVarType vt, enum fstVarDir vd,
|
||||
uint32_t len, const char *nam, fstHandle aliasHandle,
|
||||
const char *type, enum fstSupplementalVarType svt, enum fstSupplementalDataType sdt);
|
||||
void fstWriterEmitValueChange(void *ctx, fstHandle handle, const void *val);
|
||||
void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const void *val, uint32_t len);
|
||||
void fstWriterEmitDumpActive(void *ctx, int enable);
|
||||
void fstWriterEmitTimeChange(void *ctx, uint64_t tim);
|
||||
void fstWriterFlushContext(void *ctx);
|
||||
int fstWriterGetDumpSizeLimitReached(void *ctx);
|
||||
int fstWriterGetFseekFailed(void *ctx);
|
||||
void fstWriterSetAttrBegin(void *ctx, enum fstAttrType attrtype, int subtype,
|
||||
const char *attrname, uint64_t arg);
|
||||
void fstWriterSetAttrEnd(void *ctx);
|
||||
void fstWriterSetComment(void *ctx, const char *comm);
|
||||
void fstWriterSetDate(void *ctx, const char *dat);
|
||||
void fstWriterSetDumpSizeLimit(void *ctx, uint64_t numbytes);
|
||||
void fstWriterSetEnvVar(void *ctx, const char *envvar);
|
||||
void fstWriterSetFileType(void *ctx, enum fstFileType filetype);
|
||||
void fstWriterSetPackType(void *ctx, int typ); /* type = 0 (libz), 1 (fastlz) */
|
||||
void fstWriterSetParallelMode(void *ctx, int enable);
|
||||
void fstWriterSetRepackOnClose(void *ctx, int enable); /* type = 0 (none), 1 (libz) */
|
||||
void fstWriterSetScope(void *ctx, enum fstScopeType scopetype,
|
||||
const char *scopename, const char *scopecomp);
|
||||
void fstWriterSetSourceInstantiationStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath);
|
||||
void fstWriterSetSourceStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath);
|
||||
void fstWriterSetTimescale(void *ctx, int ts);
|
||||
void fstWriterSetTimescaleFromString(void *ctx, const char *s);
|
||||
void fstWriterSetTimezero(void *ctx, int64_t tim);
|
||||
void fstWriterSetUpscope(void *ctx);
|
||||
void fstWriterSetVersion(void *ctx, const char *vers);
|
||||
|
||||
void fstWriterSetPackType(void *ctx, int typ); /* type = 0 (libz), 1 (fastlz) */
|
||||
void fstWriterSetRepackOnClose(void *ctx, int enable); /* type = 0 (none), 1 (libz) */
|
||||
void fstWriterSetParallelMode(void *ctx, int enable);
|
||||
void fstWriterSetDumpSizeLimit(void *ctx, uint64_t numbytes);
|
||||
int fstWriterGetDumpSizeLimitReached(void *ctx);
|
||||
int fstWriterGetFseekFailed(void *ctx);
|
||||
|
||||
void *fstWriterCreate(const char *nam, int use_compressed_hier);
|
||||
void fstWriterClose(void *ctx);
|
||||
void fstWriterSetDate(void *ctx, const char *dat);
|
||||
void fstWriterSetVersion(void *ctx, const char *vers);
|
||||
void fstWriterSetComment(void *ctx, const char *comm);
|
||||
void fstWriterSetEnvVar(void *ctx, const char *envvar);
|
||||
void fstWriterSetTimescale(void *ctx, int ts);
|
||||
void fstWriterSetTimescaleFromString(void *ctx, const char *s);
|
||||
void fstWriterSetTimezero(void *ctx, int64_t tim);
|
||||
void fstWriterSetScope(void *ctx, enum fstScopeType scopetype,
|
||||
const char *scopename, const char *scopecomp);
|
||||
void fstWriterSetUpscope(void *ctx);
|
||||
void fstWriterEmitValueChange(void *ctx, fstHandle handle, const void *val);
|
||||
void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const void *val, uint32_t len);
|
||||
void fstWriterEmitDumpActive(void *ctx, int enable);
|
||||
void fstWriterEmitTimeChange(void *ctx, uint64_t tim);
|
||||
void fstWriterFlushContext(void *ctx);
|
||||
void fstWriterSetAttrBegin(void *ctx, enum fstAttrType attrtype, int subtype,
|
||||
const char *attrname, uint64_t arg);
|
||||
void fstWriterSetAttrEnd(void *ctx);
|
||||
|
||||
/*
|
||||
* reader functions
|
||||
*/
|
||||
void *fstReaderOpen(const char *nam);
|
||||
void *fstReaderOpenForUtilitiesOnly(void);
|
||||
void fstReaderClose(void *ctx);
|
||||
|
||||
int fstReaderProcessHier(void *ctx, FILE *vcdhandle);
|
||||
int fstReaderIterateHierRewind(void *ctx);
|
||||
void fstReaderClose(void *ctx);
|
||||
void fstReaderClrFacProcessMask(void *ctx, fstHandle facidx);
|
||||
void fstReaderClrFacProcessMaskAll(void *ctx);
|
||||
uint64_t fstReaderGetAliasCount(void *ctx);
|
||||
const char * fstReaderGetCurrentFlatScope(void *ctx);
|
||||
void * fstReaderGetCurrentScopeUserInfo(void *ctx);
|
||||
int fstReaderGetCurrentScopeLen(void *ctx);
|
||||
const char * fstReaderGetDateString(void *ctx);
|
||||
int fstReaderGetDoubleEndianMatchState(void *ctx);
|
||||
uint64_t fstReaderGetDumpActivityChangeTime(void *ctx, uint32_t idx);
|
||||
unsigned char fstReaderGetDumpActivityChangeValue(void *ctx, uint32_t idx);
|
||||
uint64_t fstReaderGetEndTime(void *ctx);
|
||||
int fstReaderGetFacProcessMask(void *ctx, fstHandle facidx);
|
||||
int fstReaderGetFileType(void *ctx);
|
||||
int fstReaderGetFseekFailed(void *ctx);
|
||||
fstHandle fstReaderGetMaxHandle(void *ctx);
|
||||
uint64_t fstReaderGetMemoryUsedByWriter(void *ctx);
|
||||
uint32_t fstReaderGetNumberDumpActivityChanges(void *ctx);
|
||||
uint64_t fstReaderGetScopeCount(void *ctx);
|
||||
uint64_t fstReaderGetStartTime(void *ctx);
|
||||
signed char fstReaderGetTimescale(void *ctx);
|
||||
int64_t fstReaderGetTimezero(void *ctx);
|
||||
uint64_t fstReaderGetValueChangeSectionCount(void *ctx);
|
||||
char * fstReaderGetValueFromHandleAtTime(void *ctx, uint64_t tim, fstHandle facidx, char *buf);
|
||||
uint64_t fstReaderGetVarCount(void *ctx);
|
||||
const char * fstReaderGetVersionString(void *ctx);
|
||||
struct fstHier *fstReaderIterateHier(void *ctx);
|
||||
int fstReaderIterateHierRewind(void *ctx);
|
||||
int fstReaderIterBlocks(void *ctx,
|
||||
void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value),
|
||||
void *user_callback_data_pointer, FILE *vcdhandle);
|
||||
int fstReaderIterBlocks2(void *ctx,
|
||||
void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value),
|
||||
void (*value_change_callback_varlen)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value, uint32_t len),
|
||||
void *user_callback_data_pointer, FILE *vcdhandle);
|
||||
void fstReaderIterBlocksSetNativeDoublesOnCallback(void *ctx, int enable);
|
||||
void * fstReaderOpen(const char *nam);
|
||||
void * fstReaderOpenForUtilitiesOnly(void);
|
||||
const char * fstReaderPopScope(void *ctx);
|
||||
int fstReaderProcessHier(void *ctx, FILE *vcdhandle);
|
||||
const char * fstReaderPushScope(void *ctx, const char *nam, void *user_info);
|
||||
void fstReaderResetScope(void *ctx);
|
||||
void fstReaderSetFacProcessMask(void *ctx, fstHandle facidx);
|
||||
void fstReaderSetFacProcessMaskAll(void *ctx);
|
||||
void fstReaderSetLimitTimeRange(void *ctx, uint64_t start_time, uint64_t end_time);
|
||||
void fstReaderSetUnlimitedTimeRange(void *ctx);
|
||||
|
||||
void fstReaderResetScope(void *ctx);
|
||||
const char *fstReaderPopScope(void *ctx);
|
||||
const char *fstReaderPushScope(void *ctx, const char *nam, void *user_info);
|
||||
const char *fstReaderGetCurrentFlatScope(void *ctx);
|
||||
void *fstReaderGetCurrentScopeUserInfo(void *ctx);
|
||||
int fstReaderGetCurrentScopeLen(void *ctx);
|
||||
|
||||
signed char fstReaderGetTimescale(void *ctx);
|
||||
int64_t fstReaderGetTimezero(void *ctx);
|
||||
uint64_t fstReaderGetStartTime(void *ctx);
|
||||
uint64_t fstReaderGetEndTime(void *ctx);
|
||||
uint64_t fstReaderGetMemoryUsedByWriter(void *ctx);
|
||||
uint64_t fstReaderGetScopeCount(void *ctx);
|
||||
uint64_t fstReaderGetVarCount(void *ctx);
|
||||
fstHandle fstReaderGetMaxHandle(void *ctx);
|
||||
uint64_t fstReaderGetAliasCount(void *ctx);
|
||||
uint64_t fstReaderGetValueChangeSectionCount(void *ctx);
|
||||
int fstReaderGetDoubleEndianMatchState(void *ctx);
|
||||
const char *fstReaderGetVersionString(void *ctx);
|
||||
const char *fstReaderGetDateString(void *ctx);
|
||||
int fstReaderGetFseekFailed(void *ctx);
|
||||
|
||||
void fstReaderSetLimitTimeRange(void *ctx, uint64_t start_time, uint64_t end_time);
|
||||
void fstReaderSetUnlimitedTimeRange(void *ctx);
|
||||
|
||||
uint32_t fstReaderGetNumberDumpActivityChanges(void *ctx);
|
||||
uint64_t fstReaderGetDumpActivityChangeTime(void *ctx, uint32_t idx);
|
||||
unsigned char fstReaderGetDumpActivityChangeValue(void *ctx, uint32_t idx);
|
||||
|
||||
int fstReaderGetFacProcessMask(void *ctx, fstHandle facidx);
|
||||
void fstReaderSetFacProcessMask(void *ctx, fstHandle facidx);
|
||||
void fstReaderClrFacProcessMask(void *ctx, fstHandle facidx);
|
||||
void fstReaderSetFacProcessMaskAll(void *ctx);
|
||||
void fstReaderClrFacProcessMaskAll(void *ctx);
|
||||
|
||||
void fstReaderIterBlocksSetNativeDoublesOnCallback(void *ctx, int enable);
|
||||
|
||||
int fstReaderIterBlocks(void *ctx,
|
||||
void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value),
|
||||
void *user_callback_data_pointer, FILE *vcdhandle);
|
||||
|
||||
int fstReaderIterBlocks2(void *ctx,
|
||||
void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value),
|
||||
void (*value_change_callback_varlen)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value, uint32_t len),
|
||||
void *user_callback_data_pointer, FILE *vcdhandle);
|
||||
|
||||
char *fstReaderGetValueFromHandleAtTime(void *ctx, uint64_t tim, fstHandle facidx, char *buf);
|
||||
|
||||
/*
|
||||
* utility functions
|
||||
*/
|
||||
int fstUtilityBinToEsc(unsigned char *d, unsigned char *s, int len);
|
||||
int fstUtilityEscToBin(unsigned char *d, unsigned char *s, int len);
|
||||
int fstUtilityBinToEsc(unsigned char *d, unsigned char *s, int len);
|
||||
int fstUtilityEscToBin(unsigned char *d, unsigned char *s, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue