fstapi.h File Reference

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <zlib.h>
#include <inttypes.h>
#include <unistd.h>
#include <time.h>

Go to the source code of this file.

Data Structures

struct  fstHier

Defines

#define FST_RDLOAD   "FSTLOAD | "

Typedefs

typedef uint32_t fstHandle

Enumerations

enum  fstBlockType {
  FST_BL_HDR = 0, FST_BL_VCDATA = 1, FST_BL_BLACKOUT = 2, FST_BL_GEOM = 3,
  FST_BL_HIER = 4, FST_BL_ZWRAPPER = 254, FST_BL_SKIP = 255
}
enum  fstScopeType {
  FST_ST_VCD_MIN = 0, FST_ST_VCD_MODULE = 0, FST_ST_VCD_TASK = 1, FST_ST_VCD_FUNCTION = 2,
  FST_ST_VCD_BEGIN = 3, FST_ST_VCD_FORK = 4, FST_ST_VCD_MAX = 4, FST_ST_MAX = 4,
  FST_ST_VCD_SCOPE = 254, FST_ST_VCD_UPSCOPE = 255
}
enum  fstVarType {
  FST_VT_VCD_MIN = 0, FST_VT_VCD_EVENT = 0, FST_VT_VCD_INTEGER = 1, FST_VT_VCD_PARAMETER = 2,
  FST_VT_VCD_REAL = 3, FST_VT_VCD_REAL_PARAMETER = 4, FST_VT_VCD_REG = 5, FST_VT_VCD_SUPPLY0 = 6,
  FST_VT_VCD_SUPPLY1 = 7, FST_VT_VCD_TIME = 8, FST_VT_VCD_TRI = 9, FST_VT_VCD_TRIAND = 10,
  FST_VT_VCD_TRIOR = 11, FST_VT_VCD_TRIREG = 12, FST_VT_VCD_TRI0 = 13, FST_VT_VCD_TRI1 = 14,
  FST_VT_VCD_WAND = 15, FST_VT_VCD_WIRE = 16, FST_VT_VCD_WOR = 17, FST_VT_VCD_PORT = 18,
  FST_VT_VCD_ARRAY = 19, FST_VT_VCD_REALTIME = 20, FST_VT_VCD_MAX = 20, FST_VT_GEN_STRING = 254,
  FST_VT_GEN_MEMBLOCK = 255
}
enum  fstVarDir {
  FST_VD_IMPLICIT = 0, FST_VD_INPUT = 1, FST_VD_OUTPUT = 2, FST_VD_INOUT = 3,
  FST_VD_MAX = 3
}
enum  fstHierType { FST_HT_SCOPE = 0, FST_HT_UPSCOPE = 1, FST_HT_VAR = 2, FST_HT_MAX = 2 }

Functions

fstHandle fstWriterCreateVar (void *ctx, enum fstVarType vt, enum fstVarDir vd, uint32_t len, const char *nam, fstHandle aliasHandle)
void fstWriterSetPackType (void *ctx, int typ)
void fstWriterSetRepackOnClose (void *ctx, int enable)
void fstWriterSetDumpSizeLimit (void *ctx, uint64_t numbytes)
int fstWriterGetDumpSizeLimitReached (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 fstWriterSetTimescale (void *ctx, int ts)
void fstWriterSetTimescaleFromString (void *ctx, const char *s)
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 fstWriterEmitDumpActive (void *ctx, int enable)
void fstWriterEmitTimeChange (void *ctx, uint64_t tim)
void fstWriterFlushContext (void *ctx)
void * fstReaderOpen (const char *nam)
void fstReaderClose (void *ctx)
int fstReaderProcessHier (void *ctx, FILE *vcdhandle)
int fstReaderIterateHierRewind (void *ctx)
struct fstHierfstReaderIterateHier (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)
signed char fstReaderGetTimescale (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)
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)
char * fstReaderGetValueFromHandleAtTime (void *ctx, uint64_t tim, fstHandle facidx, char *buf)

Define Documentation

#define FST_RDLOAD   "FSTLOAD | "

Typedef Documentation

typedef uint32_t fstHandle

Enumeration Type Documentation

Enumerator:
FST_BL_HDR 
FST_BL_VCDATA 
FST_BL_BLACKOUT 
FST_BL_GEOM 
FST_BL_HIER 
FST_BL_ZWRAPPER 
FST_BL_SKIP 

00043                   {
00044     FST_BL_HDR                 = 0,
00045     FST_BL_VCDATA              = 1,
00046     FST_BL_BLACKOUT            = 2,
00047     FST_BL_GEOM                = 3,
00048     FST_BL_HIER                = 4,
00049 
00050     FST_BL_ZWRAPPER            = 254,   /* indicates that whole trace is gz wrapped */
00051     FST_BL_SKIP                = 255    /* used while block is being written */
00052 };

Enumerator:
FST_HT_SCOPE 
FST_HT_UPSCOPE 
FST_HT_VAR 
FST_HT_MAX 

00107                  {
00108     FST_HT_SCOPE       = 0,
00109     FST_HT_UPSCOPE     = 1,
00110     FST_HT_VAR         = 2,
00111 
00112     FST_HT_MAX         = 2
00113 };

Enumerator:
FST_ST_VCD_MIN 
FST_ST_VCD_MODULE 
FST_ST_VCD_TASK 
FST_ST_VCD_FUNCTION 
FST_ST_VCD_BEGIN 
FST_ST_VCD_FORK 
FST_ST_VCD_MAX 
FST_ST_MAX 
FST_ST_VCD_SCOPE 
FST_ST_VCD_UPSCOPE 

00054                   {
00055     FST_ST_VCD_MIN             = 0,
00056     FST_ST_VCD_MODULE          = 0,
00057     FST_ST_VCD_TASK            = 1,
00058     FST_ST_VCD_FUNCTION        = 2,
00059     FST_ST_VCD_BEGIN           = 3,
00060     FST_ST_VCD_FORK            = 4,
00061     FST_ST_VCD_MAX             = 4,
00062 
00063     FST_ST_MAX                 = 4,
00064 
00065     FST_ST_VCD_SCOPE           = 254,
00066     FST_ST_VCD_UPSCOPE         = 255
00067 };

enum fstVarDir
Enumerator:
FST_VD_IMPLICIT 
FST_VD_INPUT 
FST_VD_OUTPUT 
FST_VD_INOUT 
FST_VD_MAX 

00098                {
00099     FST_VD_IMPLICIT    = 0,
00100     FST_VD_INPUT       = 1,
00101     FST_VD_OUTPUT      = 2,
00102     FST_VD_INOUT       = 3,
00103 
00104     FST_VD_MAX         = 3
00105 };

enum fstVarType
Enumerator:
FST_VT_VCD_MIN 
FST_VT_VCD_EVENT 
FST_VT_VCD_INTEGER 
FST_VT_VCD_PARAMETER 
FST_VT_VCD_REAL 
FST_VT_VCD_REAL_PARAMETER 
FST_VT_VCD_REG 
FST_VT_VCD_SUPPLY0 
FST_VT_VCD_SUPPLY1 
FST_VT_VCD_TIME 
FST_VT_VCD_TRI 
FST_VT_VCD_TRIAND 
FST_VT_VCD_TRIOR 
FST_VT_VCD_TRIREG 
FST_VT_VCD_TRI0 
FST_VT_VCD_TRI1 
FST_VT_VCD_WAND 
FST_VT_VCD_WIRE 
FST_VT_VCD_WOR 
FST_VT_VCD_PORT 
FST_VT_VCD_ARRAY 
FST_VT_VCD_REALTIME 
FST_VT_VCD_MAX 
FST_VT_GEN_STRING 
FST_VT_GEN_MEMBLOCK 

00069                 {
00070     FST_VT_VCD_MIN             = 0,     /* start of VCD datatypes */
00071     FST_VT_VCD_EVENT           = 0,
00072     FST_VT_VCD_INTEGER         = 1,
00073     FST_VT_VCD_PARAMETER       = 2,
00074     FST_VT_VCD_REAL            = 3,
00075     FST_VT_VCD_REAL_PARAMETER  = 4,
00076     FST_VT_VCD_REG             = 5,
00077     FST_VT_VCD_SUPPLY0         = 6,
00078     FST_VT_VCD_SUPPLY1         = 7,
00079     FST_VT_VCD_TIME            = 8,  
00080     FST_VT_VCD_TRI             = 9,
00081     FST_VT_VCD_TRIAND          = 10,
00082     FST_VT_VCD_TRIOR           = 11,
00083     FST_VT_VCD_TRIREG          = 12,
00084     FST_VT_VCD_TRI0            = 13,
00085     FST_VT_VCD_TRI1            = 14,
00086     FST_VT_VCD_WAND            = 15,
00087     FST_VT_VCD_WIRE            = 16,
00088     FST_VT_VCD_WOR             = 17,
00089     FST_VT_VCD_PORT            = 18,
00090     FST_VT_VCD_ARRAY           = 19,    /* used to define the rownum (index) port on the array */
00091     FST_VT_VCD_REALTIME        = 20,
00092     FST_VT_VCD_MAX             = 20,    /* end of VCD datatypes */
00093 
00094     FST_VT_GEN_STRING          = 254,   /* generic string type   (max len is defined as the len in fstWriterCreateVar() */
00095     FST_VT_GEN_MEMBLOCK        = 255    /* generic memblock type (max len is defined as the len in fstWriterCreateVar() */
00096 };


Function Documentation

void fstReaderClose ( void *  ctx  ) 

References fstReaderContext::blackout_activity, fstReaderContext::blackout_times, fstReaderContext::f, fstReaderContext::fh, fstReaderContext::filename, fstReaderContext::filename_unpacked, fstReaderDeallocateRvatData(), fstReaderDeallocateScopeData(), fstReaderContext::process_mask, fstReaderContext::rvat_sig_offs, fstReaderContext::signal_lens, fstReaderContext::signal_typs, and fstReaderContext::temp_signal_value_buf.

Referenced by fst_parse(), and fstReaderOpen().

03023 {
03024 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
03025 
03026 if(xc)
03027         {
03028         fstReaderDeallocateScopeData(xc);
03029         fstReaderDeallocateRvatData(xc);
03030         free(xc->rvat_sig_offs); xc->rvat_sig_offs = NULL;
03031 
03032         free(xc->process_mask); xc->process_mask = NULL;
03033         free(xc->blackout_times); xc->blackout_times = NULL;
03034         free(xc->blackout_activity); xc->blackout_activity = NULL;
03035         free(xc->temp_signal_value_buf); xc->temp_signal_value_buf = NULL;
03036         free(xc->signal_typs); xc->signal_typs = NULL;
03037         free(xc->signal_lens); xc->signal_lens = NULL;
03038         free(xc->filename); xc->filename = NULL;
03039 
03040         if(xc->fh) 
03041                 { 
03042                 fclose(xc->fh); xc->fh = NULL; 
03043 #ifdef __MINGW32__
03044                 if(xc->fh_name)
03045                         {
03046                         unlink(xc->fh_name);
03047                         free(xc->fh_name); xc->fh_name = NULL;
03048                         }
03049 #endif
03050                 }
03051 
03052         if(xc->f) 
03053                 { 
03054                 fclose(xc->f); xc->f = NULL; 
03055                 if(xc->filename_unpacked)
03056                         {
03057                         unlink(xc->filename_unpacked);
03058                         free(xc->filename_unpacked);
03059                         }
03060                 }
03061 
03062         free(xc);
03063         }
03064 }

void fstReaderClrFacProcessMask ( void *  ctx,
fstHandle  facidx 
)

References fstReaderContext::maxhandle, and fstReaderContext::process_mask.

01999 {
02000 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02001                                  
02002 if(xc)
02003         { 
02004         facidx--;
02005         if(facidx<xc->maxhandle)
02006                 {
02007                 int idx = facidx/8;
02008                 int bitpos = facidx&7;
02009 
02010                 xc->process_mask[idx] &= (~(1<<bitpos));
02011                 }
02012         }
02013 }

void fstReaderClrFacProcessMaskAll ( void *  ctx  ) 

References fstReaderContext::maxhandle, and fstReaderContext::process_mask.

02028 {
02029 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02030                                  
02031 if(xc)
02032         { 
02033         memset(xc->process_mask, 0x00, (xc->maxhandle+7)/8);
02034         }
02035 }

uint64_t fstReaderGetAliasCount ( void *  ctx  ) 

References fstReaderContext::num_alias.

02091 {
02092 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02093 return(xc ? xc->num_alias : 0);
02094 }

const char* fstReaderGetCurrentFlatScope ( void *  ctx  ) 

References fstReaderContext::curr_flat_hier_nam.

01862 {
01863 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
01864 if(xc)
01865         {
01866         return(xc->curr_flat_hier_nam ? xc->curr_flat_hier_nam : "");
01867         }
01868         else
01869         {
01870         return(NULL);
01871         }
01872 }

void* fstReaderGetCurrentScopeUserInfo ( void *  ctx  ) 

References fstReaderContext::curr_hier, and fstCurrHier::user_info.

01876 {
01877 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
01878 if(xc)
01879         {
01880         return(xc->curr_hier ? xc->curr_hier->user_info : NULL);
01881         }
01882         else
01883         {
01884         return(NULL);
01885         }
01886 }

const char* fstReaderGetDateString ( void *  ctx  ) 

References fstReaderContext::date.

02119 {
02120 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02121 return(xc ? xc->date : NULL);
02122 }

int fstReaderGetDoubleEndianMatchState ( void *  ctx  ) 

References fstReaderContext::double_endian_match.

02105 {
02106 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02107 return(xc ? xc->double_endian_match : 0);
02108 }

uint64_t fstReaderGetDumpActivityChangeTime ( void *  ctx,
uint32_t  idx 
)

References fstReaderContext::blackout_times, and fstReaderContext::num_blackouts.

02133 {
02134 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02135 
02136 if(xc && (idx < xc->num_blackouts) && (xc->blackout_times))
02137         {
02138         return(xc->blackout_times[idx]);
02139         }
02140         else
02141         {
02142         return(0);
02143         }
02144 }

unsigned char fstReaderGetDumpActivityChangeValue ( void *  ctx,
uint32_t  idx 
)

References fstReaderContext::blackout_activity, and fstReaderContext::num_blackouts.

02148 {
02149 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02150 
02151 if(xc && (idx < xc->num_blackouts) && (xc->blackout_activity))
02152         {
02153         return(xc->blackout_activity[idx]);
02154         }
02155         else
02156         {
02157         return(0);
02158         }
02159 }

uint64_t fstReaderGetEndTime ( void *  ctx  ) 

References fstReaderContext::end_time.

02056 {
02057 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02058 return(xc ? xc->end_time : 0);
02059 }

int fstReaderGetFacProcessMask ( void *  ctx,
fstHandle  facidx 
)

References fstReaderContext::maxhandle, and fstReaderContext::process_mask.

01962 {
01963 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
01964                                  
01965 if(xc)
01966         {      
01967         facidx--;
01968         if(facidx<xc->maxhandle)
01969                 {
01970                 int process_idx = facidx/8;
01971                 int process_bit = facidx&7;
01972 
01973                 return( (xc->process_mask[process_idx]&(1<<process_bit)) != 0 );
01974                 }
01975         }
01976 return(0);
01977 }

fstHandle fstReaderGetMaxHandle ( void *  ctx  ) 

References fstReaderContext::maxhandle.

02084 {
02085 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02086 return(xc ? xc->maxhandle : 0);
02087 }

uint64_t fstReaderGetMemoryUsedByWriter ( void *  ctx  ) 

References fstReaderContext::mem_used_by_writer.

02063 {
02064 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02065 return(xc ? xc->mem_used_by_writer : 0);
02066 }

uint32_t fstReaderGetNumberDumpActivityChanges ( void *  ctx  ) 

References fstReaderContext::num_blackouts.

02126 {
02127 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02128 return(xc ? xc->num_blackouts : 0);
02129 }

uint64_t fstReaderGetScopeCount ( void *  ctx  ) 

References fstReaderContext::scope_count.

02070 {
02071 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02072 return(xc ? xc->scope_count : 0);
02073 }

uint64_t fstReaderGetStartTime ( void *  ctx  ) 

References fstReaderContext::start_time.

02049 {
02050 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02051 return(xc ? xc->start_time : 0);
02052 }

signed char fstReaderGetTimescale ( void *  ctx  ) 

References fstReaderContext::timescale.

02042 {
02043 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02044 return(xc ? xc->timescale : 0);
02045 }

uint64_t fstReaderGetValueChangeSectionCount ( void *  ctx  ) 

References fstReaderContext::vc_section_count.

02098 {
02099 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02100 return(xc ? xc->vc_section_count : 0);
02101 }

char* fstReaderGetValueFromHandleAtTime ( void *  ctx,
uint64_t  tim,
fstHandle  facidx,
char *  buf 
)

References fstReaderContext::double_endian_match, fstReaderContext::end_time, fstReaderContext::f, FST_BL_SKIP, FST_BL_VCDATA, FST_RCV_STR, FST_VT_VCD_REAL, fstExtractRvatDataFromFrame(), fstFread(), fstGetVarint32(), fstGetVarint64(), fstReaderDeallocateRvatData(), fstReaderUint64(), fstReaderVarint32WithSkip(), fstReaderVarint64(), fstReaderContext::maxhandle, fstReaderContext::rvat_beg_tim, fstReaderContext::rvat_chain_facidx, fstReaderContext::rvat_chain_len, fstReaderContext::rvat_chain_mem, fstReaderContext::rvat_chain_pos_idx, fstReaderContext::rvat_chain_pos_tidx, fstReaderContext::rvat_chain_pos_time, fstReaderContext::rvat_chain_pos_valid, fstReaderContext::rvat_chain_table, fstReaderContext::rvat_chain_table_lengths, fstReaderContext::rvat_data_valid, fstReaderContext::rvat_end_tim, fstReaderContext::rvat_frame_data, fstReaderContext::rvat_frame_maxhandle, fstReaderContext::rvat_sig_offs, fstReaderContext::rvat_time_table, fstReaderContext::rvat_vc_maxhandle, fstReaderContext::rvat_vc_start, fstReaderContext::signal_lens, and fstReaderContext::signal_typs.

03882 {
03883 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
03884 off_t blkpos = 0, prev_blkpos;
03885 uint64_t beg_tim, end_tim, beg_tim2, end_tim2;
03886 int sectype;
03887 int secnum = 0;
03888 uint64_t seclen;
03889 uint64_t tsec_uclen = 0, tsec_clen = 0;
03890 uint64_t tsec_nitems;
03891 uint64_t frame_uclen, frame_clen;
03892 uint64_t mem_required_for_traversal;
03893 off_t indx_pntr, indx_pos;
03894 long chain_clen;
03895 unsigned char *chain_cmem;
03896 unsigned char *pnt;
03897 fstHandle idx, pidx=0, i;
03898 uint64_t pval;
03899 
03900 if((!xc) || (!facidx) || (facidx > xc->maxhandle) || (!buf))
03901         {
03902         return(NULL);
03903         }
03904 
03905 if(!xc->rvat_sig_offs)
03906         {
03907         uint32_t cur_offs = 0;
03908 
03909         xc->rvat_sig_offs = calloc(xc->maxhandle, sizeof(uint32_t));
03910         for(i=0;i<xc->maxhandle;i++)
03911                 {
03912                 xc->rvat_sig_offs[i] = cur_offs;
03913                 cur_offs += xc->signal_lens[i];
03914                 }
03915         }
03916 
03917 if(xc->rvat_data_valid)
03918         {
03919         if((xc->rvat_beg_tim <= tim) && (tim <= xc->rvat_end_tim))
03920                 {
03921                 goto process_value;
03922                 }
03923 
03924         fstReaderDeallocateRvatData(xc);
03925         }
03926 
03927 xc->rvat_chain_pos_valid = 0;
03928 
03929 for(;;)
03930         {
03931         fseeko(xc->f, (prev_blkpos = blkpos), SEEK_SET);
03932 
03933         sectype = fgetc(xc->f);
03934         seclen = fstReaderUint64(xc->f);
03935 
03936         if((sectype == EOF) || (sectype == FST_BL_SKIP) || (!seclen))
03937                 {
03938                 return(NULL); /* if this loop exits on break, it's successful */
03939                 }
03940 
03941         blkpos++;
03942         if(sectype != FST_BL_VCDATA)
03943                 {
03944                 blkpos += seclen;
03945                 continue;
03946                 }
03947 
03948         beg_tim = fstReaderUint64(xc->f);
03949         end_tim = fstReaderUint64(xc->f);
03950 
03951         if((beg_tim <= tim) && (tim <= end_tim))
03952                 {
03953                 if((tim == end_tim) && (tim != xc->end_time))
03954                         {
03955                         off_t cached_pos = ftello(xc->f);
03956                         fseeko(xc->f, blkpos, SEEK_SET);
03957 
03958                         sectype = fgetc(xc->f);
03959                         seclen = fstReaderUint64(xc->f);
03960 
03961                         beg_tim2 = fstReaderUint64(xc->f);
03962                         end_tim2 = fstReaderUint64(xc->f);
03963 
03964                         if((sectype != FST_BL_VCDATA) || (!seclen) || (beg_tim2 != tim))
03965                                 {
03966                                 blkpos = prev_blkpos;
03967                                 break;
03968                                 }
03969                         beg_tim = beg_tim2;
03970                         end_tim = end_tim2;
03971                         fseeko(xc->f, cached_pos, SEEK_SET);
03972                         }
03973                 break;
03974                 }
03975 
03976         blkpos += seclen;
03977         secnum++;
03978         }
03979 
03980 xc->rvat_beg_tim = beg_tim;
03981 xc->rvat_end_tim = end_tim;
03982 
03983 mem_required_for_traversal = fstReaderUint64(xc->f);
03984 #ifdef FST_DEBUG
03985 printf("rvat sec: %d seclen: %d begtim: %d endtim: %d\n",
03986         secnum, (int)seclen, (int)beg_tim, (int)end_tim);
03987 printf("\tmem_required_for_traversal: %d\n", (int)mem_required_for_traversal);
03988 #endif
03989 
03990 /* process time block */
03991 {
03992 unsigned char *ucdata;
03993 unsigned char *cdata;
03994 unsigned long destlen = tsec_uclen;
03995 unsigned long sourcelen = tsec_clen;
03996 int rc;
03997 unsigned char *tpnt;
03998 uint64_t tpval;
03999 int ti;
04000 
04001 fseeko(xc->f, blkpos + seclen - 24, SEEK_SET);
04002 tsec_uclen = fstReaderUint64(xc->f);
04003 tsec_clen = fstReaderUint64(xc->f);
04004 tsec_nitems = fstReaderUint64(xc->f);
04005 #ifdef FST_DEBUG
04006 printf("\ttime section unc: %d, com: %d (%d items)\n", 
04007         (int)tsec_uclen, (int)tsec_clen, (int)tsec_nitems);
04008 #endif          
04009 ucdata = malloc(tsec_uclen);
04010 destlen = tsec_uclen;
04011 sourcelen = tsec_clen;
04012         
04013 fseeko(xc->f, -24 - ((off_t)tsec_clen), SEEK_CUR);
04014 if(tsec_uclen != tsec_clen)
04015         {
04016         cdata = malloc(tsec_clen);
04017         fstFread(cdata, tsec_clen, 1, xc->f);
04018         
04019         rc = uncompress(ucdata, &destlen, cdata, sourcelen);
04020                         
04021         if(rc != Z_OK)
04022                 {
04023                 printf("tsec uncompress rc = %d\n", rc);
04024                 exit(255);
04025                 }
04026         
04027         free(cdata);
04028         }
04029         else
04030         {
04031         fstFread(ucdata, tsec_uclen, 1, xc->f);
04032         }
04033 
04034 xc->rvat_time_table = calloc(tsec_nitems, sizeof(uint64_t));
04035 tpnt = ucdata;
04036 tpval = 0;
04037 for(ti=0;ti<tsec_nitems;ti++)
04038         {
04039         int skiplen;
04040         uint64_t val = fstGetVarint64(tpnt, &skiplen);
04041         tpval = xc->rvat_time_table[ti] = tpval + val;
04042         tpnt += skiplen;        
04043         }
04044 
04045 free(ucdata);
04046 }
04047 
04048 fseeko(xc->f, blkpos+32, SEEK_SET);
04049 
04050 frame_uclen = fstReaderVarint64(xc->f);
04051 frame_clen = fstReaderVarint64(xc->f);
04052 xc->rvat_frame_maxhandle = fstReaderVarint64(xc->f);
04053 xc->rvat_frame_data = malloc(frame_uclen);
04054 
04055 if(frame_uclen == frame_clen)
04056         {
04057         fstFread(xc->rvat_frame_data, frame_uclen, 1, xc->f);
04058         }
04059         else
04060         {
04061         unsigned char *mc = malloc(frame_clen);
04062         int rc;
04063 
04064         unsigned long destlen = frame_uclen;
04065         unsigned long sourcelen = frame_clen;
04066 
04067         fstFread(mc, sourcelen, 1, xc->f);
04068         rc = uncompress(xc->rvat_frame_data, &destlen, mc, sourcelen);
04069         if(rc != Z_OK)
04070                 {
04071                 printf("decompress rc: %d\n", rc);
04072                 exit(255);
04073                 }
04074         free(mc);
04075         }
04076 
04077 xc->rvat_vc_maxhandle = fstReaderVarint64(xc->f);
04078 xc->rvat_vc_start = ftello(xc->f);      /* points to '!' character */
04079 
04080 #ifdef FST_DEBUG
04081 printf("\tframe_uclen: %d, frame_clen: %d, frame_maxhandle: %d\n",
04082         (int)frame_uclen, (int)frame_clen, (int)xc->rvat_frame_maxhandle);
04083 printf("\tvc_maxhandle: %d\n", (int)xc->rvat_vc_maxhandle);
04084 #endif
04085 
04086 indx_pntr = blkpos + seclen - 24 -tsec_clen -8;
04087 fseeko(xc->f, indx_pntr, SEEK_SET);
04088 chain_clen = fstReaderUint64(xc->f);
04089 indx_pos = indx_pntr - chain_clen;
04090 #ifdef FST_DEBUG
04091 printf("\tindx_pos: %d (%d bytes)\n", (int)indx_pos, (int)chain_clen);
04092 #endif
04093 chain_cmem = malloc(chain_clen);
04094 fseeko(xc->f, indx_pos, SEEK_SET);
04095 fstFread(chain_cmem, chain_clen, 1, xc->f);
04096         
04097 xc->rvat_chain_table = malloc((xc->rvat_vc_maxhandle+1) * sizeof(off_t));
04098 xc->rvat_chain_table_lengths = malloc((xc->rvat_vc_maxhandle+1) * sizeof(uint32_t));
04099 
04100 pnt = chain_cmem;
04101 idx = 0;
04102 pval = 0;
04103 do
04104         {
04105         int skiplen;
04106         uint64_t val = fstGetVarint32(pnt, &skiplen);
04107                 
04108         if(val&1)
04109                 {
04110                 pval = xc->rvat_chain_table[idx] = pval + (val >> 1);
04111                 if(idx) { xc->rvat_chain_table_lengths[pidx] = pval - xc->rvat_chain_table[pidx]; }
04112                 pidx = idx++;
04113                 }
04114                 else
04115                 {
04116                 int loopcnt = val >> 1;
04117                 for(i=0;i<loopcnt;i++)
04118                         {
04119                         xc->rvat_chain_table[idx++] = 0;
04120                         }
04121                 }
04122                 
04123         pnt += skiplen;
04124         } while (pnt != (chain_cmem + chain_clen));
04125 
04126 free(chain_cmem); 
04127 xc->rvat_chain_table[idx] = indx_pos - xc->rvat_vc_start;
04128 xc->rvat_chain_table_lengths[pidx] = xc->rvat_chain_table[idx] - xc->rvat_chain_table[pidx];
04129 
04130 #ifdef FST_DEBUG
04131 printf("\tdecompressed chain idx len: %"PRIu32"\n", idx);
04132 #endif
04133 
04134 xc->rvat_data_valid = 1;
04135 
04136 /* all data at this point is loaded or resident in fst cache, process and return appropriate value */ 
04137 process_value:
04138 if(facidx > xc->rvat_vc_maxhandle)
04139         {
04140         return(NULL);
04141         }
04142 
04143 facidx--; /* scale down for array which starts at zero */
04144 
04145 
04146 if(((tim == xc->rvat_beg_tim)&&(!xc->rvat_chain_table[facidx])) || (!xc->rvat_chain_table[facidx]))
04147         {
04148         return(fstExtractRvatDataFromFrame(xc, facidx, buf));
04149         }
04150 
04151 if(facidx != xc->rvat_chain_facidx)
04152         {
04153         if(xc->rvat_chain_mem)
04154                 {
04155                 free(xc->rvat_chain_mem);
04156                 xc->rvat_chain_mem = NULL;
04157 
04158                 xc->rvat_chain_pos_valid = 0;
04159                 }
04160         }
04161 
04162 if(!xc->rvat_chain_mem)
04163         {
04164         uint32_t skiplen;
04165         fseeko(xc->f, xc->rvat_vc_start + xc->rvat_chain_table[facidx], SEEK_SET);
04166         xc->rvat_chain_len = fstReaderVarint32WithSkip(xc->f, &skiplen);
04167         if(xc->rvat_chain_len)
04168                 {
04169                 unsigned char *mu = malloc(xc->rvat_chain_len);
04170                 unsigned char *mc = malloc(xc->rvat_chain_table_lengths[facidx]);
04171                 unsigned long destlen = xc->rvat_chain_len;
04172                 unsigned long sourcelen = xc->rvat_chain_table_lengths[facidx];
04173                 int rc;
04174                 
04175                 fstFread(mc, xc->rvat_chain_table_lengths[facidx], 1, xc->f);
04176                 rc = uncompress(mu, &destlen, mc, sourcelen);
04177                 free(mc);
04178         
04179                 if(rc != Z_OK)
04180                         {
04181                         printf("\tclen: %d (rc=%d)\n", (int)xc->rvat_chain_len, rc);
04182                         exit(255);
04183                         }
04184         
04185                 /* data to process is for(j=0;j<destlen;j++) in mu[j] */
04186                 xc->rvat_chain_mem = mu;
04187                 }
04188                 else
04189                 {
04190                 int destlen = xc->rvat_chain_table_lengths[facidx] - skiplen;
04191                 unsigned char *mu = malloc(xc->rvat_chain_len = destlen);
04192                 fstFread(mu, destlen, 1, xc->f);
04193                 /* data to process is for(j=0;j<destlen;j++) in mu[j] */
04194                 xc->rvat_chain_mem = mu;
04195                 }
04196 
04197         xc->rvat_chain_facidx = facidx;
04198         }       
04199 
04200 /* process value chain here */
04201 
04202 {
04203 uint32_t tidx = 0, ptidx = 0;
04204 uint32_t tdelta;
04205 int skiplen;
04206 int iprev = xc->rvat_chain_len;
04207 uint32_t pvli = 0;
04208 int pskip = 0;
04209 
04210 if((xc->rvat_chain_pos_valid)&&(tim >= xc->rvat_chain_pos_time))
04211         {
04212         i = xc->rvat_chain_pos_idx;
04213         tidx = xc->rvat_chain_pos_tidx;
04214         }
04215         else
04216         {
04217         i = 0;
04218         tidx = 0;
04219         xc->rvat_chain_pos_time = xc->rvat_beg_tim;
04220         }
04221 
04222 if(xc->signal_lens[facidx] == 1)
04223         {
04224         while(i<xc->rvat_chain_len)
04225                 {
04226                 uint32_t vli = fstGetVarint32(xc->rvat_chain_mem + i, &skiplen);
04227                 uint32_t shcnt = 2 << (vli & 1);
04228                 tdelta = vli >> shcnt;
04229 
04230                 if(xc->rvat_time_table[tidx + tdelta] <= tim)
04231                         {
04232                         iprev = i;
04233                         pvli = vli;
04234                         ptidx = tidx;
04235                         pskip = skiplen;
04236 
04237                         tidx += tdelta;
04238                         i+=skiplen;
04239                         }
04240                         else
04241                         {
04242                         break;
04243                         }
04244                 }
04245         if(iprev != xc->rvat_chain_len)
04246                 {
04247                 xc->rvat_chain_pos_tidx = ptidx;
04248                 xc->rvat_chain_pos_idx = iprev;
04249                 xc->rvat_chain_pos_time = tim;
04250                 xc->rvat_chain_pos_valid = 1;
04251 
04252                 if(!(pvli & 1))
04253                         {
04254                         buf[0] = ((pvli >> 1) & 1) | '0'; 
04255                         }
04256                         else
04257                         {
04258                         buf[0] = FST_RCV_STR[((pvli >> 1) & 7)];
04259                         }
04260                 buf[1] = 0;
04261                 return(buf);
04262                 }
04263                 else
04264                 {
04265                 return(fstExtractRvatDataFromFrame(xc, facidx, buf));
04266                 }
04267         }
04268         else
04269         {
04270         while(i<xc->rvat_chain_len)
04271                 {
04272                 uint32_t vli = fstGetVarint32(xc->rvat_chain_mem + i, &skiplen);
04273                 tdelta = vli >> 1;
04274 
04275                 if(xc->rvat_time_table[tidx + tdelta] <= tim)
04276                         {
04277                         iprev = i;
04278                         pvli = vli;
04279                         ptidx = tidx;
04280                         pskip = skiplen;
04281 
04282                         tidx += tdelta;
04283                         i+=skiplen;
04284 
04285                         if(!(pvli & 1))
04286                                 {
04287                                 i+=((xc->signal_lens[facidx]+7)/8);
04288                                 }
04289                                 else
04290                                 {
04291                                 i+=xc->signal_lens[facidx];
04292                                 }
04293                         }
04294                         else
04295                         {
04296                         break;
04297                         }
04298                 }
04299 
04300         if(iprev != xc->rvat_chain_len)
04301                 {
04302                 unsigned char *vdata = xc->rvat_chain_mem + iprev + pskip;
04303 
04304                 xc->rvat_chain_pos_tidx = ptidx;
04305                 xc->rvat_chain_pos_idx = iprev;
04306                 xc->rvat_chain_pos_time = tim;
04307                 xc->rvat_chain_pos_valid = 1;
04308 
04309                 if(xc->signal_typs[facidx] != FST_VT_VCD_REAL)
04310                         {
04311                         if(!(pvli & 1))
04312                                 {
04313                                 int byte = 0;
04314                                 int bit;
04315                                 int j;
04316 
04317                                 for(j=0;j<xc->signal_lens[facidx];j++)
04318                                         {
04319                                         unsigned char ch;
04320                                         byte = j/8;
04321                                         bit = 7 - (j & 7);
04322                                         ch = ((vdata[byte] >> bit) & 1) | '0';
04323                                         buf[j] = ch;
04324                                         }
04325                                 buf[j] = 0;
04326 
04327                                 return(buf);
04328                                 }
04329                                 else
04330                                 {
04331                                 memcpy(buf, vdata, xc->signal_lens[facidx]);
04332                                 buf[xc->signal_lens[facidx]] = 0;
04333                                 return(buf);
04334                                 }
04335                         }
04336                         else
04337                         {
04338                         double d;
04339                         unsigned char *clone_d = (unsigned char *)&d;
04340                         unsigned char bufd[8];
04341                         unsigned char *srcdata;
04342 
04343                         if(!(pvli & 1)) /* very rare case, but possible */
04344                                 {
04345                                 int bit;
04346                                 int j;
04347 
04348                                 for(j=0;j<8;j++)
04349                                         {
04350                                         unsigned char ch;
04351                                         bit = 7 - (j & 7);
04352                                         ch = ((vdata[0] >> bit) & 1) | '0';
04353                                         bufd[j] = ch;
04354                                         }
04355         
04356                                 srcdata = bufd;
04357                                 }
04358                                 else
04359                                 {
04360                                 srcdata = vdata;
04361                                 }
04362 
04363                         if(xc->double_endian_match)
04364                                 {
04365                                 memcpy(clone_d, srcdata, 8);
04366                                 }
04367                                 else
04368                                 {
04369                                 int j;
04370 
04371                                 for(j=0;j<8;j++)
04372                                         {
04373                                         clone_d[j] = srcdata[7-j];
04374                                         }
04375                                 }
04376 
04377                         sprintf(buf, "r%.16g", d);
04378                         return(buf);
04379                         }
04380                 }
04381                 else
04382                 {
04383                 return(fstExtractRvatDataFromFrame(xc, facidx, buf));
04384                 }
04385         }               
04386 }
04387 
04388 /* return(NULL); */
04389 }

uint64_t fstReaderGetVarCount ( void *  ctx  ) 

References fstReaderContext::var_count.

02077 {
02078 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02079 return(xc ? xc->var_count : 0);
02080 }

const char* fstReaderGetVersionString ( void *  ctx  ) 

References fstReaderContext::version.

02112 {
02113 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02114 return(xc ? xc->version : NULL);
02115 }

struct fstHier* fstReaderIterateHier ( void *  ctx  )  [read]

References fstReaderContext::current_handle, fstReaderContext::do_rewind, fstReaderContext::fh, FST_HT_SCOPE, FST_HT_UPSCOPE, FST_HT_VAR, FST_ST_VCD_SCOPE, FST_ST_VCD_UPSCOPE, FST_VT_VCD_ARRAY, FST_VT_VCD_EVENT, FST_VT_VCD_INTEGER, FST_VT_VCD_PARAMETER, FST_VT_VCD_PORT, FST_VT_VCD_REAL, FST_VT_VCD_REAL_PARAMETER, FST_VT_VCD_REALTIME, FST_VT_VCD_REG, FST_VT_VCD_SUPPLY0, FST_VT_VCD_SUPPLY1, FST_VT_VCD_TIME, FST_VT_VCD_TRI, FST_VT_VCD_TRI0, FST_VT_VCD_TRI1, FST_VT_VCD_TRIAND, FST_VT_VCD_TRIOR, FST_VT_VCD_TRIREG, FST_VT_VCD_WAND, FST_VT_VCD_WIRE, FST_VT_VCD_WOR, fstReaderRecreateHierFile(), fstReaderVarint32(), fstReaderContext::hier, fstHier::htyp, fstHier::scope, fstReaderContext::str_scope_comp, fstReaderContext::str_scope_nam, fstHier::u, and fstHier::var.

02348 {
02349 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02350 int isfeof;
02351 fstHandle alias;
02352 char *pnt;
02353 int ch;
02354 
02355 if(!xc) return(NULL);
02356 
02357 if(!xc->fh)
02358         {
02359         if(!fstReaderRecreateHierFile(xc))
02360                 {
02361                 return(NULL);
02362                 }
02363         }
02364 
02365 if(xc->do_rewind)
02366         {
02367         xc->do_rewind = 0;
02368         xc->current_handle = 0;
02369         fseeko(xc->fh, 0, SEEK_SET);
02370         clearerr(xc->fh);
02371         }
02372 
02373 if(!(isfeof=feof(xc->fh)))
02374         {
02375         int tag = fgetc(xc->fh);
02376         switch(tag)
02377                 {
02378                 case FST_ST_VCD_SCOPE:
02379                         xc->hier.htyp = FST_HT_SCOPE;
02380                         xc->hier.u.scope.typ = fgetc(xc->fh);
02381                         xc->hier.u.scope.name = pnt = xc->str_scope_nam;
02382                         while((ch = fgetc(xc->fh))) 
02383                                 {
02384                                 *(pnt++) = ch; 
02385                                 }; /* scopename */
02386                         *pnt = 0;
02387 
02388                         xc->hier.u.scope.component = pnt = xc->str_scope_comp;
02389                         while((ch = fgetc(xc->fh))) 
02390                                 {
02391                                 *(pnt++) = ch; 
02392                                 }; /* scopecomp */
02393                         *pnt = 0;
02394                         break;
02395 
02396                 case FST_ST_VCD_UPSCOPE:
02397                         xc->hier.htyp = FST_HT_UPSCOPE;
02398                         break;
02399 
02400                 case FST_VT_VCD_EVENT:
02401                 case FST_VT_VCD_INTEGER:
02402                 case FST_VT_VCD_PARAMETER:
02403                 case FST_VT_VCD_REAL:
02404                 case FST_VT_VCD_REAL_PARAMETER:
02405                 case FST_VT_VCD_REG:
02406                 case FST_VT_VCD_SUPPLY0:
02407                 case FST_VT_VCD_SUPPLY1:
02408                 case FST_VT_VCD_TIME:
02409                 case FST_VT_VCD_TRI:
02410                 case FST_VT_VCD_TRIAND:
02411                 case FST_VT_VCD_TRIOR:
02412                 case FST_VT_VCD_TRIREG:
02413                 case FST_VT_VCD_TRI0:
02414                 case FST_VT_VCD_TRI1:
02415                 case FST_VT_VCD_WAND:
02416                 case FST_VT_VCD_WIRE:
02417                 case FST_VT_VCD_WOR:
02418                 case FST_VT_VCD_PORT:
02419                 case FST_VT_VCD_ARRAY:
02420                 case FST_VT_VCD_REALTIME:
02421                         xc->hier.htyp = FST_HT_VAR;
02422 
02423                         xc->hier.u.var.typ = tag;
02424                         xc->hier.u.var.direction = fgetc(xc->fh);
02425                         xc->hier.u.var.name = pnt = xc->str_scope_nam;
02426                         while((ch = fgetc(xc->fh))) 
02427                                 {
02428                                 *(pnt++) = ch; 
02429                                 }; /* varname */
02430                         *pnt = 0;
02431                         xc->hier.u.var.length = fstReaderVarint32(xc->fh);
02432                         if(tag == FST_VT_VCD_PORT)
02433                                 {
02434                                 xc->hier.u.var.length -= 2; /* removal of delimiting spaces */
02435                                 xc->hier.u.var.length /= 3; /* port -> signal size adjust */
02436                                 }
02437 
02438                         alias = fstReaderVarint32(xc->fh);
02439 
02440                         if(!alias)
02441                                 {
02442                                 xc->current_handle++;
02443                                 xc->hier.u.var.handle = xc->current_handle;
02444                                 xc->hier.u.var.is_alias = 0;
02445                                 }
02446                                 else
02447                                 {
02448                                 xc->hier.u.var.handle = alias;
02449                                 xc->hier.u.var.is_alias = 1;
02450                                 }
02451                 
02452                         break;
02453 
02454                 default:
02455                         isfeof = 1; 
02456                         break;
02457                 }
02458         }
02459 
02460 return(!isfeof ? &xc->hier : NULL);
02461 }

int fstReaderIterateHierRewind ( void *  ctx  ) 

References fstReaderContext::do_rewind, fstReaderContext::fh, and fstReaderRecreateHierFile().

02328 {
02329 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02330 int pass_status = 0;
02331 
02332 if(xc)
02333         {
02334         pass_status = 1;
02335         if(!xc->fh)
02336                 {
02337                 pass_status = fstReaderRecreateHierFile(xc);
02338                 }
02339 
02340         xc->do_rewind = 1;
02341         }
02342 
02343 return(pass_status);
02344 }

int fstReaderIterBlocks ( void *  ctx,
void(*)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value)  value_change_callback,
void *  user_callback_data_pointer,
FILE *  vcdhandle 
)

References fstReaderContext::blackout_activity, fstReaderContext::blackout_times, fstReaderContext::double_endian_match, fstReaderContext::f, fastlz_decompress(), FST_BL_SKIP, FST_BL_VCDATA, FST_RCV_STR, FST_VT_VCD_PORT, FST_VT_VCD_REAL, fstFread(), fstFwrite(), fstGetVarint32(), fstGetVarint32NoSkip(), fstGetVarint64(), fstReaderUint64(), fstReaderVarint32WithSkip(), fstReaderVarint64(), fstVcdID(), fstVcdIDForFwrite(), fstReaderContext::limit_range_end, fstReaderContext::limit_range_start, fstReaderContext::limit_range_valid, fstReaderContext::maxhandle, fstReaderContext::native_doubles_for_cb, fstReaderContext::num_blackouts, fstReaderContext::process_mask, fstReaderContext::signal_lens, fstReaderContext::signal_typs, fstReaderContext::temp_signal_value_buf, and fstReaderContext::vc_section_count.

Referenced by fst_parse().

03075 {
03076 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
03077 
03078 uint64_t previous_time = UINT64_MAX;
03079 uint64_t *time_table = NULL;
03080 uint64_t tsec_nitems;
03081 int secnum = 0;
03082 off_t blkpos = 0;
03083 uint64_t seclen, beg_tim, end_tim;
03084 uint64_t frame_uclen, frame_clen, frame_maxhandle, vc_maxhandle; 
03085 off_t vc_start;
03086 off_t indx_pntr, indx_pos;
03087 off_t *chain_table = NULL;
03088 uint32_t *chain_table_lengths = NULL;
03089 unsigned char *chain_cmem;
03090 unsigned char *pnt;
03091 long chain_clen;
03092 fstHandle idx, pidx=0, i;
03093 uint64_t pval;
03094 uint64_t vc_maxhandle_largest = 0;
03095 uint64_t tsec_uclen = 0, tsec_clen = 0;
03096 int sectype;
03097 uint64_t mem_required_for_traversal;
03098 unsigned char *mem_for_traversal = NULL;
03099 uint32_t traversal_mem_offs;
03100 uint32_t *scatterptr, *headptr, *length_remaining;
03101 uint32_t cur_blackout = 0;
03102 int packtype;
03103 
03104 if(!xc) return(0);
03105 
03106 scatterptr = calloc(xc->maxhandle, sizeof(uint32_t));
03107 headptr = calloc(xc->maxhandle, sizeof(uint32_t));
03108 length_remaining = calloc(xc->maxhandle, sizeof(uint32_t));
03109 
03110 for(;;)
03111         {
03112         uint32_t *tc_head = NULL;
03113         traversal_mem_offs = 0;
03114 
03115         fseeko(xc->f, blkpos, SEEK_SET);
03116         
03117         sectype = fgetc(xc->f);
03118         seclen = fstReaderUint64(xc->f);
03119 
03120         if((sectype == EOF) || (sectype == FST_BL_SKIP))
03121                 {
03122 #ifdef FST_DEBUG
03123                 printf("<< EOF >>\n");
03124 #endif
03125                 break;
03126                 }
03127 
03128         blkpos++;
03129         if(sectype != FST_BL_VCDATA)
03130                 {
03131                 blkpos += seclen;
03132                 continue;
03133                 }
03134 
03135         if(!seclen) break;
03136 
03137         beg_tim = fstReaderUint64(xc->f);
03138         end_tim = fstReaderUint64(xc->f);
03139 
03140         if(xc->limit_range_valid)
03141                 {
03142                 if(beg_tim < xc->limit_range_start)
03143                         {
03144                         blkpos += seclen;
03145                         continue;
03146                         }
03147 
03148                 if(beg_tim > xc->limit_range_end) /* likely the compare in for(i=0;i<tsec_nitems;i++) below would do this earlier */
03149                         {
03150                         break;
03151                         }
03152                 }
03153 
03154 
03155         mem_required_for_traversal = fstReaderUint64(xc->f);
03156         mem_for_traversal = malloc(mem_required_for_traversal + 66); /* add in potential fastlz overhead */
03157 #ifdef FST_DEBUG
03158         printf("sec: %d seclen: %d begtim: %d endtim: %d\n",
03159                 secnum, (int)seclen, (int)beg_tim, (int)end_tim);
03160         printf("\tmem_required_for_traversal: %d\n", (int)mem_required_for_traversal);
03161 #endif
03162         /* process time block */
03163         {
03164         unsigned char *ucdata;
03165         unsigned char *cdata;
03166         unsigned long destlen = tsec_uclen;
03167         unsigned long sourcelen = tsec_clen;
03168         int rc;
03169         unsigned char *tpnt;
03170         uint64_t tpval;
03171         int ti;
03172 
03173         fseeko(xc->f, blkpos + seclen - 24, SEEK_SET);
03174         tsec_uclen = fstReaderUint64(xc->f);
03175         tsec_clen = fstReaderUint64(xc->f);
03176         tsec_nitems = fstReaderUint64(xc->f);
03177 #ifdef FST_DEBUG
03178         printf("\ttime section unc: %d, com: %d (%d items)\n", 
03179                 (int)tsec_uclen, (int)tsec_clen, (int)tsec_nitems);
03180 #endif          
03181         ucdata = malloc(tsec_uclen);
03182         destlen = tsec_uclen;
03183         sourcelen = tsec_clen;
03184 
03185         fseeko(xc->f, -24 - ((off_t)tsec_clen), SEEK_CUR);
03186 
03187         if(tsec_uclen != tsec_clen)
03188                 {
03189                 cdata = malloc(tsec_clen);
03190                 fstFread(cdata, tsec_clen, 1, xc->f);
03191         
03192                 rc = uncompress(ucdata, &destlen, cdata, sourcelen);
03193                         
03194                 if(rc != Z_OK)
03195                         {
03196                         printf("tsec uncompress rc = %d\n", rc);
03197                         exit(255);
03198                         }
03199         
03200                 free(cdata);
03201                 }
03202                 else
03203                 {
03204                 fstFread(ucdata, tsec_uclen, 1, xc->f);
03205                 }
03206         
03207         free(time_table);
03208         time_table = calloc(tsec_nitems, sizeof(uint64_t));
03209         tpnt = ucdata;
03210         tpval = 0;
03211         for(ti=0;ti<tsec_nitems;ti++)
03212                 {
03213                 int skiplen;
03214                 uint64_t val = fstGetVarint64(tpnt, &skiplen);
03215                 tpval = time_table[ti] = tpval + val;
03216                 tpnt += skiplen;        
03217                 }
03218 
03219         tc_head = calloc(tsec_nitems, sizeof(uint32_t));
03220         free(ucdata);
03221         }
03222 
03223         fseeko(xc->f, blkpos+32, SEEK_SET);
03224 
03225         frame_uclen = fstReaderVarint64(xc->f);
03226         frame_clen = fstReaderVarint64(xc->f);
03227         frame_maxhandle = fstReaderVarint64(xc->f);
03228 
03229         if(secnum == 0)
03230                 {
03231                 if(beg_tim != time_table[0])
03232                         {
03233                         unsigned char *mu = malloc(frame_uclen);
03234                         uint32_t sig_offs = 0;
03235 
03236                         if(fv)
03237                                 {
03238                                 if(beg_tim) { fprintf(fv, "#%"PRIu64"\n", beg_tim); }
03239                                 if((xc->num_blackouts)&&(cur_blackout != xc->num_blackouts))
03240                                         {
03241                                         if(beg_tim == xc->blackout_times[cur_blackout])
03242                                                 {
03243                                                 fprintf(fv, "$dump%s $end\n", (xc->blackout_activity[cur_blackout++]) ? "on" : "off");
03244                                                 }
03245                                         }
03246                                 }
03247 
03248                         if(frame_uclen == frame_clen)
03249                                 {
03250                                 fstFread(mu, frame_uclen, 1, xc->f);
03251                                 }
03252                                 else
03253                                 {
03254                                 unsigned char *mc = malloc(frame_clen);
03255                                 int rc;
03256 
03257                                 unsigned long destlen = frame_uclen;
03258                                 unsigned long sourcelen = frame_clen;
03259 
03260                                 fstFread(mc, sourcelen, 1, xc->f);
03261                                 rc = uncompress(mu, &destlen, mc, sourcelen);
03262                                 if(rc != Z_OK)
03263                                         {
03264                                         printf("rc: %d\n", rc);
03265                                         exit(255);
03266                                         }
03267                                 free(mc);
03268                                 }
03269 
03270 
03271                         for(idx=0;idx<frame_maxhandle;idx++)
03272                                 {
03273                                 int process_idx = idx/8;
03274                                 int process_bit = idx&7;
03275 
03276                                 if(xc->process_mask[process_idx]&(1<<process_bit))
03277                                         {
03278                                         if(xc->signal_lens[idx] == 1)
03279                                                 {
03280                                                 unsigned char val = mu[sig_offs];
03281                                                 if(value_change_callback)
03282                                                         {
03283                                                         xc->temp_signal_value_buf[0] = val;
03284                                                         xc->temp_signal_value_buf[1] = 0;
03285                                                         value_change_callback(user_callback_data_pointer, beg_tim, idx+1, xc->temp_signal_value_buf);
03286                                                         }
03287                                                         else
03288                                                         {
03289                                                         if(fv)
03290                                                                 {
03291                                                                 int vcdid_len;
03292                                                                 const char *vcd_id = fstVcdIDForFwrite(idx+1, &vcdid_len);
03293                                                                 fputc(val, fv);
03294                                                                 fstFwrite(vcd_id, vcdid_len, 1, fv);
03295                                                                 fputc('\n', fv);
03296                                                                 }
03297                                                         }
03298                                                 }
03299                                                 else
03300                                                 {
03301                                                 if(xc->signal_typs[idx] != FST_VT_VCD_REAL)
03302                                                         {
03303                                                         if(value_change_callback)
03304                                                                 {
03305                                                                 memcpy(xc->temp_signal_value_buf, mu+sig_offs, xc->signal_lens[idx]);
03306                                                                 xc->temp_signal_value_buf[xc->signal_lens[idx]] = 0;
03307                                                                 value_change_callback(user_callback_data_pointer, beg_tim, idx+1, xc->temp_signal_value_buf);
03308                                                                 }
03309                                                                 else
03310                                                                 {
03311                                                                 if(fv)
03312                                                                         {
03313                                                                         int vcdid_len;
03314                                                                         const char *vcd_id = fstVcdIDForFwrite(idx+1, &vcdid_len);
03315                                                                         fputc((xc->signal_typs[idx] != FST_VT_VCD_PORT) ? 'b' : 'p', fv);
03316                                                                         fstFwrite(mu+sig_offs, xc->signal_lens[idx], 1, fv);
03317                                                                         fputc(' ', fv);
03318                                                                         fstFwrite(vcd_id, vcdid_len, 1, fv);
03319                                                                         fputc('\n', fv);
03320                                                                         }
03321                                                                 }
03322                                                         }
03323                                                         else
03324                                                         {
03325                                                         double d;
03326                                                         unsigned char *clone_d;
03327                                                         unsigned char *srcdata = mu+sig_offs;
03328                 
03329                                                         if(value_change_callback)
03330                                                                 {
03331                                                                 if(xc->native_doubles_for_cb)
03332                                                                         {
03333                                                                         if(xc->double_endian_match)
03334                                                                                 {
03335                                                                                 clone_d = srcdata;
03336                                                                                 }
03337                                                                                 else
03338                                                                                 {
03339                                                                                 int j;
03340                 
03341                                                                                 clone_d = (unsigned char *)&d;
03342                                                                                 for(j=0;j<8;j++)
03343                                                                                         {
03344                                                                                         clone_d[j] = srcdata[7-j];
03345                                                                                         }
03346                                                                                 }
03347                                                                         value_change_callback(user_callback_data_pointer, beg_tim, idx+1, clone_d);
03348                                                                         }
03349                                                                         else
03350                                                                         {
03351                                                                         clone_d = (unsigned char *)&d;
03352                                                                         if(xc->double_endian_match)
03353                                                                                 {
03354                                                                                 memcpy(clone_d, srcdata, 8);
03355                                                                                 }
03356                                                                                 else
03357                                                                                 {
03358                                                                                 int j;
03359                 
03360                                                                                 for(j=0;j<8;j++)
03361                                                                                         {
03362                                                                                         clone_d[j] = srcdata[7-j];
03363                                                                                         }
03364                                                                                 }
03365                                                                         sprintf((char *)xc->temp_signal_value_buf, "%.16g", d);
03366                                                                         value_change_callback(user_callback_data_pointer, beg_tim, idx+1, xc->temp_signal_value_buf);
03367                                                                         }
03368                                                                 }
03369                                                                 else
03370                                                                 {
03371                                                                 if(fv)
03372                                                                         {
03373                                                                         clone_d = (unsigned char *)&d;
03374                                                                         if(xc->double_endian_match)
03375                                                                                 {
03376                                                                                 memcpy(clone_d, srcdata, 8);
03377                                                                                 }
03378                                                                                 else
03379                                                                                 {
03380                                                                                 int j;
03381                 
03382                                                                                 for(j=0;j<8;j++)
03383                                                                                         {
03384                                                                                         clone_d[j] = srcdata[7-j];
03385                                                                                         }
03386                                                                                 }
03387                                                 
03388                                                                         fprintf(fv, "r%.16g %s\n", d, fstVcdID(idx+1));
03389                                                                         }
03390                                                                 }
03391                                                         }
03392                                                 }
03393                                         }       
03394 
03395                                 sig_offs += xc->signal_lens[idx];
03396                                 }
03397 
03398                         free(mu);
03399                         fseeko(xc->f, -((off_t)frame_clen), SEEK_CUR);
03400                         }
03401                 }
03402 
03403         fseeko(xc->f, (off_t)frame_clen, SEEK_CUR); /* skip past compressed data */
03404 
03405         vc_maxhandle = fstReaderVarint64(xc->f);
03406         vc_start = ftello(xc->f);       /* points to '!' character */
03407         packtype = fgetc(xc->f);
03408 
03409 #ifdef FST_DEBUG
03410         printf("\tframe_uclen: %d, frame_clen: %d, frame_maxhandle: %d\n",
03411                 (int)frame_uclen, (int)frame_clen, (int)frame_maxhandle);
03412         printf("\tvc_maxhandle: %d, packtype: %c\n", (int)vc_maxhandle, packtype);
03413 #endif
03414 
03415         indx_pntr = blkpos + seclen - 24 -tsec_clen -8;
03416         fseeko(xc->f, indx_pntr, SEEK_SET);
03417         chain_clen = fstReaderUint64(xc->f);
03418         indx_pos = indx_pntr - chain_clen;
03419 #ifdef FST_DEBUG
03420         printf("\tindx_pos: %d (%d bytes)\n", (int)indx_pos, (int)chain_clen);
03421 #endif
03422         chain_cmem = malloc(chain_clen);
03423         if(!chain_cmem) goto block_err;
03424         fseeko(xc->f, indx_pos, SEEK_SET);
03425         fstFread(chain_cmem, chain_clen, 1, xc->f);
03426         
03427         if(vc_maxhandle > vc_maxhandle_largest)
03428                 {
03429                 free(chain_table);
03430                 free(chain_table_lengths);
03431 
03432                 vc_maxhandle_largest = vc_maxhandle;
03433                 chain_table = malloc((vc_maxhandle+1) * sizeof(off_t));
03434                 chain_table_lengths = malloc((vc_maxhandle+1) * sizeof(uint32_t));
03435                 }
03436 
03437         if(!chain_table || !chain_table_lengths) goto block_err;
03438 
03439         pnt = chain_cmem;
03440         idx = 0;
03441         pval = 0;
03442         do
03443                 {
03444                 int skiplen;
03445                 uint64_t val = fstGetVarint32(pnt, &skiplen);
03446                 
03447                 if(val&1)
03448                         {
03449                         pval = chain_table[idx] = pval + (val >> 1);
03450                         if(idx) { chain_table_lengths[pidx] = pval - chain_table[pidx]; }
03451                         pidx = idx++;
03452                         }
03453                         else
03454                         {
03455                         int loopcnt = val >> 1;
03456                         for(i=0;i<loopcnt;i++)
03457                                 {
03458                                 chain_table[idx++] = 0;
03459                                 }
03460                         }
03461                 
03462                 pnt += skiplen;
03463                 } while (pnt != (chain_cmem + chain_clen));
03464         chain_table[idx] = indx_pos - vc_start;
03465         chain_table_lengths[pidx] = chain_table[idx] - chain_table[pidx];
03466 #ifdef FST_DEBUG
03467         printf("\tdecompressed chain idx len: %"PRIu32"\n", idx);
03468 #endif
03469         /* check compressed VC data */
03470         if(idx > xc->maxhandle) idx = xc->maxhandle;
03471         for(i=0;i<idx;i++)
03472                 {
03473                 if(chain_table[i])
03474                         {
03475                         int process_idx = i/8;
03476                         int process_bit = i&7;
03477 
03478                         if(xc->process_mask[process_idx]&(1<<process_bit))
03479                                 {
03480                                 int rc = Z_OK;
03481                                 uint32_t val;
03482                                 uint32_t skiplen;
03483                                 uint32_t tdelta;
03484         
03485                                 fseeko(xc->f, vc_start + chain_table[i], SEEK_SET);
03486                                 val = fstReaderVarint32WithSkip(xc->f, &skiplen);
03487                                 if(val)
03488                                         {
03489                                         unsigned char *mu = mem_for_traversal + traversal_mem_offs;
03490                                         unsigned char *mc = malloc(chain_table_lengths[i]);
03491                                         unsigned long destlen = val;
03492                                         unsigned long sourcelen = chain_table_lengths[i];
03493         
03494                                         fstFread(mc, chain_table_lengths[i], 1, xc->f);
03495                                         if(packtype == 'F')
03496                                                 {
03497                                                 rc = fastlz_decompress(mc, sourcelen, mu, destlen);
03498                                                 }
03499                                                 else
03500                                                 {
03501                                                 rc = uncompress(mu, &destlen, mc, sourcelen);
03502                                                 }
03503                                         free(mc);
03504                                         /* data to process is for(j=0;j<destlen;j++) in mu[j] */
03505                                         headptr[i] = traversal_mem_offs;
03506                                         length_remaining[i] = val;
03507                                         traversal_mem_offs += val;
03508                                         }
03509                                         else
03510                                         {
03511                                         int destlen = chain_table_lengths[i] - skiplen;
03512                                         unsigned char *mu = mem_for_traversal + traversal_mem_offs;
03513                                         fstFread(mu, destlen, 1, xc->f);
03514                                         /* data to process is for(j=0;j<destlen;j++) in mu[j] */
03515                                         headptr[i] = traversal_mem_offs;
03516                                         length_remaining[i] = destlen;
03517                                         traversal_mem_offs += destlen;
03518                                         }
03519         
03520                                 if(rc != Z_OK)
03521                                         {
03522                                         printf("\tclen: %d (rc=%d)\n", (int)val, rc);
03523                                         exit(255);
03524                                         }
03525         
03526                                 if(xc->signal_lens[i] == 1)
03527                                         {
03528                                         uint32_t vli = fstGetVarint32NoSkip(mem_for_traversal + headptr[i]);
03529                                         uint32_t shcnt = 2 << (vli & 1);
03530                                         tdelta = vli >> shcnt;
03531                                         }
03532                                         else
03533                                         {
03534                                         uint32_t vli = fstGetVarint32NoSkip(mem_for_traversal + headptr[i]);
03535                                         tdelta = vli >> 1;
03536                                         }
03537         
03538                                 scatterptr[i] = tc_head[tdelta];
03539                                 tc_head[tdelta] = i+1;
03540                                 }
03541                         }
03542                 }
03543 
03544         for(i=0;i<tsec_nitems;i++)
03545                 {
03546                 uint32_t tdelta;
03547                 int skiplen;
03548                 uint32_t vli;
03549 
03550                 if(fv)
03551                         {
03552                         if(time_table[i] != previous_time)
03553                                 {
03554                                 if(xc->limit_range_valid)
03555                                         {
03556                                         if(time_table[i] > xc->limit_range_end)
03557                                                 {
03558                                                 break;
03559                                                 }
03560                                         }
03561 
03562                                 fprintf(fv, "#%"PRIu64"\n", time_table[i]);
03563                                 if((xc->num_blackouts)&&(cur_blackout != xc->num_blackouts))
03564                                         {
03565                                         if(time_table[i] == xc->blackout_times[cur_blackout])
03566                                                 {
03567                                                 fprintf(fv, "$dump%s $end\n", (xc->blackout_activity[cur_blackout++]) ? "on" : "off");
03568                                                 }
03569                                         }
03570                                 previous_time = time_table[i];
03571                                 }
03572                         }
03573         
03574                 while(tc_head[i])
03575                         {
03576                         idx = tc_head[i] - 1;
03577                         vli = fstGetVarint32(mem_for_traversal + headptr[idx], &skiplen);
03578 
03579                         if(xc->signal_lens[idx] == 1)
03580                                 {
03581                                 unsigned char val;
03582                                 if(!(vli & 1))
03583                                         {
03584                                         tdelta = vli >> 2;
03585                                         val = ((vli >> 1) & 1) | '0'; 
03586                                         }
03587                                         else
03588                                         {
03589                                         tdelta = vli >> 4;
03590                                         val = FST_RCV_STR[((vli >> 1) & 7)];
03591                                         }
03592 
03593                                 if(value_change_callback)
03594                                         {
03595                                         xc->temp_signal_value_buf[0] = val;
03596                                         xc->temp_signal_value_buf[1] = 0;
03597                                         value_change_callback(user_callback_data_pointer, time_table[i], idx+1, xc->temp_signal_value_buf);
03598                                         }
03599                                         else
03600                                         {
03601                                         if(fv) 
03602                                                 {
03603                                                 int vcdid_len;
03604                                                 const char *vcd_id = fstVcdIDForFwrite(idx+1, &vcdid_len);
03605                                                 fputc(val, fv);
03606                                                 fstFwrite(vcd_id, vcdid_len, 1, fv);
03607                                                 fputc('\n', fv);
03608                                                 }
03609                                         }
03610                                 headptr[idx] += skiplen;
03611                                 length_remaining[idx] -= skiplen;
03612 
03613                                 tc_head[i] = scatterptr[idx];
03614                                 scatterptr[idx] = 0;
03615         
03616                                 if(length_remaining[idx])
03617                                         {
03618                                         int shamt;
03619                                         vli = fstGetVarint32NoSkip(mem_for_traversal + headptr[idx]);
03620                                         shamt = 2 << (vli & 1);
03621                                         tdelta = vli >> shamt;
03622 
03623                                         scatterptr[idx] = tc_head[i+tdelta];
03624                                         tc_head[i+tdelta] = idx+1;
03625                                         }
03626                                 }
03627                                 else
03628                                 {
03629                                 uint32_t len = xc->signal_lens[idx];
03630                                 unsigned char *vdata;
03631 
03632                                 vli = fstGetVarint32(mem_for_traversal + headptr[idx], &skiplen);
03633                                 tdelta = vli >> 1;
03634                                 vdata = mem_for_traversal + headptr[idx] + skiplen;
03635 
03636                                 if(xc->signal_typs[idx] != FST_VT_VCD_REAL)
03637                                         {
03638                                         if(!(vli & 1))
03639                                                 {
03640                                                 int byte = 0;
03641                                                 int bit;
03642                                                 int j;
03643 
03644                                                 for(j=0;j<len;j++)
03645                                                         {
03646                                                         unsigned char ch;
03647                                                         byte = j/8;
03648                                                         bit = 7 - (j & 7);
03649                                                         ch = ((vdata[byte] >> bit) & 1) | '0';
03650                                                         xc->temp_signal_value_buf[j] = ch;
03651                                                         }
03652                                                 xc->temp_signal_value_buf[j] = 0;
03653 
03654                                                 if(value_change_callback)
03655                                                         {
03656                                                         value_change_callback(user_callback_data_pointer, time_table[i], idx+1, xc->temp_signal_value_buf);
03657                                                         }
03658                                                         else
03659                                                         {
03660                                                         if(fv)  { 
03661                                                                 fputc((xc->signal_typs[idx] != FST_VT_VCD_PORT) ? 'b' : 'p', fv);
03662                                                                 fstFwrite(xc->temp_signal_value_buf, len, 1, fv);
03663                                                                 }
03664                                                         }
03665 
03666                                                 len = byte+1;
03667                                                 }
03668                                                 else
03669                                                 {
03670                                                 if(value_change_callback)
03671                                                         {
03672                                                         memcpy(xc->temp_signal_value_buf, vdata, len);
03673                                                         xc->temp_signal_value_buf[len] = 0;
03674                                                         value_change_callback(user_callback_data_pointer, time_table[i], idx+1, xc->temp_signal_value_buf);
03675                                                         }
03676                                                         else
03677                                                         {
03678                                                         if(fv)
03679                                                                 {
03680                                                                 fputc((xc->signal_typs[idx] != FST_VT_VCD_PORT) ? 'b' : 'p', fv);
03681                                                                 fstFwrite(vdata, len, 1, fv);
03682                                                                 }
03683                                                         }
03684                                                 }
03685                                         }
03686                                         else
03687                                         {
03688                                         double d;
03689                                         unsigned char *clone_d = (unsigned char *)&d;
03690                                         unsigned char buf[8];
03691                                         unsigned char *srcdata;
03692 
03693                                         if(!(vli & 1))  /* very rare case, but possible */
03694                                                 {
03695                                                 int bit;
03696                                                 int j;
03697 
03698                                                 for(j=0;j<8;j++)
03699                                                         {
03700                                                         unsigned char ch;
03701                                                         bit = 7 - (j & 7);
03702                                                         ch = ((vdata[0] >> bit) & 1) | '0';
03703                                                         buf[j] = ch;
03704                                                         }
03705         
03706                                                 len = 1;
03707                                                 srcdata = buf;
03708                                                 }
03709                                                 else
03710                                                 {
03711                                                 srcdata = vdata;
03712                                                 }
03713 
03714                                         if(value_change_callback)
03715                                                 {
03716                                                 if(xc->native_doubles_for_cb)
03717                                                         {
03718                                                         if(xc->double_endian_match)
03719                                                                 {
03720                                                                 clone_d = srcdata;
03721                                                                 }
03722                                                                 else
03723                                                                 {
03724                                                                 int j;
03725                 
03726                                                                 clone_d = (unsigned char *)&d;
03727                                                                 for(j=0;j<8;j++)
03728                                                                         {
03729                                                                         clone_d[j] = srcdata[7-j];
03730                                                                         }
03731                                                                 }
03732                                                         value_change_callback(user_callback_data_pointer, time_table[i], idx+1, clone_d);
03733                                                         }
03734                                                         else
03735                                                         {
03736                                                         clone_d = (unsigned char *)&d;
03737                                                         if(xc->double_endian_match)
03738                                                                 {
03739                                                                 memcpy(clone_d, srcdata, 8);
03740                                                                 }
03741                                                                 else
03742                                                                 {
03743                                                                 int j;
03744                 
03745                                                                 for(j=0;j<8;j++)
03746                                                                         {
03747                                                                         clone_d[j] = srcdata[7-j];
03748                                                                         }
03749                                                                 }
03750                                                         sprintf((char *)xc->temp_signal_value_buf, "%.16g", d);
03751                                                         value_change_callback(user_callback_data_pointer, time_table[i], idx+1, xc->temp_signal_value_buf);
03752                                                         }
03753                                                 }
03754                                                 else
03755                                                 {
03756                                                 if(fv)
03757                                                         {
03758                                                         clone_d = (unsigned char *)&d;
03759                                                         if(xc->double_endian_match)
03760                                                                 {
03761                                                                 memcpy(clone_d, srcdata, 8);
03762                                                                 }
03763                                                                 else
03764                                                                 {
03765                                                                 int j;
03766                 
03767                                                                 for(j=0;j<8;j++)
03768                                                                         {
03769                                                                         clone_d[j] = srcdata[7-j];
03770                                                                         }
03771                                                                 }
03772                                                 
03773                                                         fprintf(fv, "r%.16g", d);
03774                                                         }
03775                                                 }
03776                                         }
03777 
03778                                 if(fv) 
03779                                         {
03780                                         int vcdid_len;
03781                                         const char *vcd_id = fstVcdIDForFwrite(idx+1, &vcdid_len);
03782                                         fputc(' ', fv);
03783                                         fstFwrite(vcd_id, vcdid_len, 1, fv);
03784                                         fputc('\n', fv);
03785                                         }
03786 
03787                                 skiplen += len;
03788                                 headptr[idx] += skiplen;
03789                                 length_remaining[idx] -= skiplen;
03790 
03791                                 tc_head[i] = scatterptr[idx];
03792                                 scatterptr[idx] = 0;
03793         
03794                                 if(length_remaining[idx])
03795                                         {
03796                                         vli = fstGetVarint32NoSkip(mem_for_traversal + headptr[idx]);
03797                                         tdelta = vli >> 1;
03798 
03799                                         scatterptr[idx] = tc_head[i+tdelta];
03800                                         tc_head[i+tdelta] = idx+1;
03801                                         }
03802                                 }
03803                         }
03804                 }
03805 
03806 block_err:
03807         free(tc_head);
03808         free(chain_cmem);
03809         free(mem_for_traversal);
03810 
03811         secnum++;
03812         if(secnum == xc->vc_section_count) break; /* in case file is growing, keep with original block count */
03813         blkpos += seclen;
03814         }
03815 
03816 free(length_remaining);
03817 free(headptr);
03818 free(scatterptr);
03819 
03820 if(chain_table)
03821         {
03822         free(chain_table);
03823         free(chain_table_lengths);
03824         }
03825 
03826 free(time_table);
03827 
03828 return(1);
03829 }

void fstReaderIterBlocksSetNativeDoublesOnCallback ( void *  ctx,
int  enable 
)

References fstReaderContext::native_doubles_for_cb.

02187 {
02188 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02189 if(xc)
02190         {
02191         xc->native_doubles_for_cb = (enable != 0);
02192         }
02193 }

void* fstReaderOpen ( const char *  nam  ) 

References fstReaderContext::contains_hier_section, fstReaderContext::do_rewind, fstReaderContext::f, fstReaderContext::fh, fstReaderContext::filename, fstReaderClose(), fstReaderInit(), fstReaderContext::maxhandle, and fstReaderContext::vc_section_count.

Referenced by fst_parse().

02964 {
02965 struct fstReaderContext *xc = calloc(1, sizeof(struct fstReaderContext));
02966 
02967 if((!nam)||(!(xc->f=fopen(nam, "rb"))))
02968         {
02969         free(xc);
02970         xc=NULL;
02971         }
02972         else
02973         {
02974         int flen = strlen(nam);
02975         char *hf = calloc(1, flen + 6);
02976         int rc;
02977 
02978 #if defined(__MINGW32__) || defined(FST_MACOSX)
02979         setvbuf(xc->f, (char *)NULL, _IONBF, 0);   /* keeps gzip from acting weird in tandem with fopen */
02980 #endif
02981 
02982         memcpy(hf, nam, flen);
02983         strcpy(hf + flen, ".hier");
02984         xc->fh = fopen(hf, "rb");
02985 
02986         free(hf);
02987         xc->filename = strdup(nam);
02988         rc = fstReaderInit(xc);
02989 
02990         if((rc) && (xc->vc_section_count) && (xc->maxhandle) && ((xc->fh)||(xc->contains_hier_section)))
02991                 {
02992                 /* more init */
02993                 xc->do_rewind = 1;
02994                 }
02995                 else
02996                 {
02997                 fstReaderClose(xc);
02998                 xc = NULL;
02999                 }
03000         }
03001 
03002 return(xc);
03003 }

const char* fstReaderPopScope ( void *  ctx  ) 

References fstReaderContext::curr_flat_hier_nam, fstReaderContext::curr_hier, fstCurrHier::len, and fstCurrHier::prev.

Referenced by fstReaderResetScope().

01890 {
01891 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
01892 if(xc && xc->curr_hier)   
01893         {
01894         struct fstCurrHier *ch = xc->curr_hier;
01895         if(xc->curr_hier->prev)
01896                 {
01897                 xc->curr_flat_hier_nam[xc->curr_hier->prev->len] = 0;
01898                 }
01899                 else
01900                 {
01901                 *xc->curr_flat_hier_nam = 0;
01902                 }
01903         xc->curr_hier = xc->curr_hier->prev;
01904         free(ch);
01905         return(xc->curr_flat_hier_nam ? xc->curr_flat_hier_nam : "");
01906         }
01907 
01908 return(NULL);
01909 }

int fstReaderProcessHier ( void *  ctx,
FILE *  vcdhandle 
)

References fstReaderContext::date, fstReaderContext::fh, FST_ID_NAM_SIZ, FST_ST_VCD_SCOPE, FST_ST_VCD_UPSCOPE, FST_VT_VCD_ARRAY, FST_VT_VCD_EVENT, FST_VT_VCD_INTEGER, FST_VT_VCD_PARAMETER, FST_VT_VCD_PORT, FST_VT_VCD_REAL, FST_VT_VCD_REAL_PARAMETER, FST_VT_VCD_REALTIME, FST_VT_VCD_REG, FST_VT_VCD_SUPPLY0, FST_VT_VCD_SUPPLY1, FST_VT_VCD_TIME, FST_VT_VCD_TRI, FST_VT_VCD_TRI0, FST_VT_VCD_TRI1, FST_VT_VCD_TRIAND, FST_VT_VCD_TRIOR, FST_VT_VCD_TRIREG, FST_VT_VCD_WAND, FST_VT_VCD_WIRE, FST_VT_VCD_WOR, fstReaderRecreateHierFile(), fstReaderVarint32(), fstVcdID(), fstReaderContext::longest_signal_value_len, fstReaderContext::maxhandle, fstReaderContext::num_alias, fstReaderContext::process_mask, fstReaderContext::signal_lens, fstReaderContext::signal_typs, fstReaderContext::temp_signal_value_buf, fstReaderContext::timescale, fstReaderContext::var_count, and fstReaderContext::version.

Referenced by fstReaderInit().

02465 {
02466 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02467 char str[FST_ID_NAM_SIZ+1];
02468 char *pnt;
02469 int ch, scopetype;
02470 int vartype;
02471 uint32_t len, alias;
02472 uint32_t maxvalpos=0;
02473 int num_signal_dyn = 65536;
02474 
02475 if(!xc) return(0);
02476 
02477 xc->longest_signal_value_len = 32; /* arbitrarily set at 32...this is much longer than an expanded double */
02478 
02479 if(!xc->fh)
02480         {
02481         if(!fstReaderRecreateHierFile(xc))
02482                 {
02483                 return(0);
02484                 }
02485         }
02486 
02487 if(fv)
02488         {
02489         char time_dimension[2] = {0, 0};
02490         int time_scale = 1;
02491 
02492         fprintf(fv, "$date\n\t%s\n$end\n", xc->date);
02493         fprintf(fv, "$version\n\t%s\n$end\n", xc->version);
02494         
02495         switch(xc->timescale)
02496                 {
02497                 case 0:         break;
02498 
02499                 case -1:        time_scale = 100;               time_dimension[0] = 'm'; break;
02500                 case -2:        time_scale = 10;
02501                 case -3:                                        time_dimension[0] = 'm'; break;
02502          
02503                 case -4:        time_scale = 100;               time_dimension[0] = 'u'; break;
02504                 case -5:        time_scale = 10;
02505                 case -6:                                        time_dimension[0] = 'u'; break;
02506         
02507                 case -10:       time_scale = 100;               time_dimension[0] = 'p'; break;
02508                 case -11:       time_scale = 10;
02509                 case -12:                                       time_dimension[0] = 'p'; break;
02510         
02511                 case -13:       time_scale = 100;               time_dimension[0] = 'f'; break;
02512                 case -14:       time_scale = 10;
02513                 case -15:                                       time_dimension[0] = 'f'; break;
02514 
02515                 case -16:       time_scale = 100;               time_dimension[0] = 'a'; break;
02516                 case -17:       time_scale = 10;
02517                 case -18:                                       time_dimension[0] = 'a'; break;
02518 
02519                 case -19:       time_scale = 100;               time_dimension[0] = 'z'; break;
02520                 case -20:       time_scale = 10;
02521                 case -21:                                       time_dimension[0] = 'z'; break;
02522         
02523                 case -7:        time_scale = 100;               time_dimension[0] = 'n'; break;
02524                 case -8:        time_scale = 10;
02525                 case -9:
02526                 default:                                        time_dimension[0] = 'n'; break;
02527                 }
02528 
02529         if(fv) fprintf(fv, "$timescale\n\t%d%ss\n$end\n", time_scale, time_dimension);
02530         }
02531 
02532 xc->maxhandle = 0;
02533 xc->num_alias = 0;
02534 
02535 free(xc->signal_lens);
02536 xc->signal_lens = malloc(num_signal_dyn*sizeof(uint32_t));
02537 
02538 free(xc->signal_typs);
02539 xc->signal_typs = malloc(num_signal_dyn*sizeof(unsigned char));
02540 
02541 fseeko(xc->fh, 0, SEEK_SET);
02542 while(!feof(xc->fh))
02543         {
02544         int tag = fgetc(xc->fh);
02545         switch(tag)
02546                 {
02547                 case FST_ST_VCD_SCOPE:
02548                         scopetype = fgetc(xc->fh);
02549                         pnt = str;
02550                         while((ch = fgetc(xc->fh))) 
02551                                 {
02552                                 *(pnt++) = ch; 
02553                                 }; /* scopename */
02554                         *pnt = 0;
02555                         while(fgetc(xc->fh)) { }; /* scopecomp */
02556 
02557                         if(fv) fprintf(fv, "$scope %s %s $end\n", modtypes[scopetype], str);
02558                         break;
02559 
02560                 case FST_ST_VCD_UPSCOPE:
02561                         if(fv) fprintf(fv, "$upscope $end\n");
02562                         break;
02563 
02564                 case FST_VT_VCD_EVENT:
02565                 case FST_VT_VCD_INTEGER:
02566                 case FST_VT_VCD_PARAMETER:
02567                 case FST_VT_VCD_REAL:
02568                 case FST_VT_VCD_REAL_PARAMETER:
02569                 case FST_VT_VCD_REG:
02570                 case FST_VT_VCD_SUPPLY0:
02571                 case FST_VT_VCD_SUPPLY1:
02572                 case FST_VT_VCD_TIME:
02573                 case FST_VT_VCD_TRI:
02574                 case FST_VT_VCD_TRIAND:
02575                 case FST_VT_VCD_TRIOR:
02576                 case FST_VT_VCD_TRIREG:
02577                 case FST_VT_VCD_TRI0:
02578                 case FST_VT_VCD_TRI1:
02579                 case FST_VT_VCD_WAND:
02580                 case FST_VT_VCD_WIRE:
02581                 case FST_VT_VCD_WOR:
02582                 case FST_VT_VCD_PORT:
02583                 case FST_VT_VCD_ARRAY:
02584                 case FST_VT_VCD_REALTIME:
02585                         vartype = tag;
02586                         /* vardir = */ fgetc(xc->fh); /* unused in VCD reader, but need to advance read pointer */
02587                         pnt = str;
02588                         while((ch = fgetc(xc->fh))) 
02589                                 {
02590                                 *(pnt++) = ch; 
02591                                 }; /* varname */
02592                         *pnt = 0;
02593                         len = fstReaderVarint32(xc->fh);
02594                         alias = fstReaderVarint32(xc->fh);
02595 
02596                         if(!alias)
02597                                 {
02598                                 if(xc->maxhandle == num_signal_dyn)
02599                                         {
02600                                         num_signal_dyn *= 2;
02601                                         xc->signal_lens = realloc(xc->signal_lens, num_signal_dyn*sizeof(uint32_t));
02602                                         xc->signal_typs = realloc(xc->signal_typs, num_signal_dyn*sizeof(unsigned char));
02603                                         }
02604                                 xc->signal_lens[xc->maxhandle] = len;
02605                                 xc->signal_typs[xc->maxhandle] = vartype;
02606 
02607                                 maxvalpos+=len;
02608                                 if(len > xc->longest_signal_value_len)
02609                                         {
02610                                         xc->longest_signal_value_len = len;
02611                                         }
02612 
02613                                 if((vartype == FST_VT_VCD_REAL) || (vartype == FST_VT_VCD_REAL_PARAMETER) || (vartype == FST_VT_VCD_REALTIME))
02614                                         {
02615                                         len = 64;
02616                                         xc->signal_typs[xc->maxhandle] = FST_VT_VCD_REAL;
02617                                         }
02618                                 if(fv) 
02619                                         {
02620                                         uint32_t modlen = (vartype != FST_VT_VCD_PORT) ? len : ((len - 2) / 3);
02621                                         fprintf(fv, "$var %s %"PRIu32" %s %s $end\n", vartypes[vartype], modlen, fstVcdID(xc->maxhandle+1), str);
02622                                         }
02623                                 xc->maxhandle++;
02624                                 }
02625                                 else
02626                                 {
02627                                 if((vartype == FST_VT_VCD_REAL) || (vartype == FST_VT_VCD_REAL_PARAMETER) || (vartype == FST_VT_VCD_REALTIME))
02628                                         {
02629                                         len = 64;
02630                                         xc->signal_typs[xc->maxhandle] = FST_VT_VCD_REAL;
02631                                         }
02632                                 if(fv) 
02633                                         {
02634                                         uint32_t modlen = (vartype != FST_VT_VCD_PORT) ? len : ((len - 2) / 3);
02635                                         fprintf(fv, "$var %s %"PRIu32" %s %s $end\n", vartypes[vartype], modlen, fstVcdID(alias), str);
02636                                         }
02637                                 xc->num_alias++;
02638                                 }
02639                 
02640                         break;
02641 
02642                 default:
02643                         break;
02644                 }
02645         }
02646 if(fv) fprintf(fv, "$enddefinitions $end\n");
02647 
02648 xc->signal_lens = realloc(xc->signal_lens, xc->maxhandle*sizeof(uint32_t));
02649 xc->signal_typs = realloc(xc->signal_typs, xc->maxhandle*sizeof(unsigned char));
02650 
02651 free(xc->process_mask);
02652 xc->process_mask = calloc(1, (xc->maxhandle+7)/8);
02653 
02654 free(xc->temp_signal_value_buf);
02655 xc->temp_signal_value_buf = malloc(xc->longest_signal_value_len + 1);
02656 
02657 xc->var_count = xc->maxhandle + xc->num_alias;
02658 
02659 return(1);
02660 }

const char* fstReaderPushScope ( void *  ctx,
const char *  nam,
void *  user_info 
)

References fstReaderContext::curr_flat_hier_nam, fstReaderContext::curr_hier, fstReaderContext::flat_hier_alloc_len, fstCurrHier::len, fstCurrHier::prev, and fstCurrHier::user_info.

01924 {
01925 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
01926 if(xc)
01927         {
01928         struct fstCurrHier *ch = malloc(sizeof(struct fstCurrHier));
01929         int chl = xc->curr_hier ? xc->curr_hier->len : 0;
01930         int len = chl + 1 + strlen(nam);
01931         if(len >= xc->flat_hier_alloc_len)
01932                 {
01933                 xc->curr_flat_hier_nam = xc->curr_flat_hier_nam ? realloc(xc->curr_flat_hier_nam, len+1) : malloc(len+1);
01934                 }
01935 
01936         if(chl)
01937                 {
01938                 xc->curr_flat_hier_nam[chl] = '.';
01939                 strcpy(xc->curr_flat_hier_nam + chl + 1, nam);
01940                 }
01941                 else
01942                 {
01943                 strcpy(xc->curr_flat_hier_nam, nam);
01944                 len--;
01945                 }
01946 
01947         ch->len = len;
01948         ch->prev = xc->curr_hier;
01949         ch->user_info = user_info;
01950         xc->curr_hier = ch;
01951         return(xc->curr_flat_hier_nam);
01952         }
01953 
01954 return(NULL);
01955 }

void fstReaderResetScope ( void *  ctx  ) 

References fstReaderPopScope().

01913 {
01914 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
01915 
01916 if(xc)
01917         {
01918         while(fstReaderPopScope(xc)); /* remove any already-built scoping info */
01919         }
01920 }

void fstReaderSetFacProcessMask ( void *  ctx,
fstHandle  facidx 
)

References fstReaderContext::maxhandle, and fstReaderContext::process_mask.

01981 {
01982 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
01983                                  
01984 if(xc)
01985         { 
01986         facidx--;
01987         if(facidx<xc->maxhandle)
01988                 {
01989                 int idx = facidx/8;
01990                 int bitpos = facidx&7;
01991 
01992                 xc->process_mask[idx] |= (1<<bitpos);
01993                 }
01994         }
01995 }

void fstReaderSetFacProcessMaskAll ( void *  ctx  ) 

References fstReaderContext::maxhandle, and fstReaderContext::process_mask.

Referenced by fst_parse().

02017 {
02018 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02019                                  
02020 if(xc)
02021         { 
02022         memset(xc->process_mask, 0xff, (xc->maxhandle+7)/8);
02023         }
02024 }

void fstReaderSetLimitTimeRange ( void *  ctx,
uint64_t  start_time,
uint64_t  end_time 
)

References fstReaderContext::limit_range_end, fstReaderContext::limit_range_start, and fstReaderContext::limit_range_valid.

02163 {
02164 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02165 
02166 if(xc)
02167         {
02168         xc->limit_range_valid = 1;
02169         xc->limit_range_start = start_time;
02170         xc->limit_range_end = end_time;
02171         }
02172 }

void fstReaderSetUnlimitedTimeRange ( void *  ctx  ) 

References fstReaderContext::limit_range_valid.

02176 {
02177 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
02178 
02179 if(xc)
02180         {
02181         xc->limit_range_valid = 0;
02182         }
02183 }

void fstWriterClose ( void *  ctx  ) 

References fstBlackoutChain::active, fstWriterContext::already_in_close, fstWriterContext::already_in_flush, fstWriterContext::blackout_curr, fstWriterContext::blackout_head, fstWriterContext::compress_hier, fstWriterContext::curtime, fstWriterContext::curval_handle, fstWriterContext::curval_mem, fstWriterContext::filename, fstWriterContext::firsttime, FST_BL_BLACKOUT, FST_BL_GEOM, FST_BL_HIER, FST_BL_SKIP, FST_BL_ZWRAPPER, FST_GZIO_LEN, FST_HDR_OFFS_NUM_SCOPES, FST_HDR_OFFS_START_TIME, fstDestroyMmaps(), fstFread(), fstFtruncate(), fstFwrite(), fstMmap, fstMunmap, fstWriterEmitTimeChange(), fstWriterEmitValueChange(), fstWriterFlushContext(), fstWriterUint64(), fstWriterVarint(), fstWriterContext::geom_handle, fstWriterContext::handle, fstWriterContext::hier_file_len, fstWriterContext::hier_handle, fstWriterContext::is_initial_time, fstWriterContext::maxhandle, fstBlackoutChain::next, fstWriterContext::num_blackouts, fstWriterContext::numscopes, fstWriterContext::numsigs, fstWriterContext::repack_on_close, fstWriterContext::secnum, fstWriterContext::section_header_only, fstWriterContext::section_header_truncpos, fstWriterContext::size_limit_locked, fstWriterContext::skip_writing_section_hdr, fstWriterContext::tchn_handle, fstBlackoutChain::tim, fstWriterContext::valpos_handle, fstWriterContext::valpos_mem, fstWriterContext::vchg_mem, and fstWriterContext::vchg_siz.

00696 {
00697 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
00698 if(xc && !xc->already_in_close && !xc->already_in_flush)
00699         {
00700         unsigned char *tmem;
00701         off_t fixup_offs, tlen, hlen;
00702 
00703         xc->already_in_close = 1; /* never need to zero this out as it is freed at bottom */
00704 
00705         if(xc->section_header_only && xc->section_header_truncpos && (xc->vchg_siz <= 1) && (!xc->is_initial_time))
00706                 {
00707                 fstFtruncate(fileno(xc->handle), xc->section_header_truncpos);
00708                 fseeko(xc->handle, xc->section_header_truncpos, SEEK_SET);
00709                 xc->section_header_only = 0;
00710                 }
00711                 else
00712                 {
00713                 xc->skip_writing_section_hdr = 1;
00714                 if(!xc->size_limit_locked)
00715                         {
00716                         if(xc->is_initial_time) /* simulation time never advanced so mock up the changes as time zero ones */
00717                                 {
00718                                 fstHandle dupe_idx;
00719         
00720                                 fstWriterEmitTimeChange(xc, 0); /* emit some time change just to have one */
00721                                 for(dupe_idx = 0; dupe_idx < xc->maxhandle; dupe_idx++) /* now clone the values */
00722                                         {
00723                                         fstWriterEmitValueChange(xc, dupe_idx+1, xc->curval_mem + xc->valpos_mem[4*dupe_idx]);
00724                                         }
00725                                 }
00726                         fstWriterFlushContext(xc);
00727                         }
00728                 }
00729         fstDestroyMmaps(xc, 1);
00730 
00731         /* write out geom section */
00732         fflush(xc->geom_handle);
00733         tlen = ftello(xc->geom_handle);
00734         tmem = fstMmap(NULL, tlen, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->geom_handle), 0);
00735         if(tmem)
00736                 {
00737                 unsigned long destlen = tlen;
00738                 unsigned char *dmem = malloc(destlen);
00739                 int rc = compress2(dmem, &destlen, tmem, tlen, 9);
00740 
00741                 if((rc != Z_OK) || (destlen > tlen))
00742                         {
00743                         destlen = tlen;
00744                         }
00745 
00746                 fixup_offs = ftello(xc->handle);
00747                 fputc(FST_BL_SKIP, xc->handle);                 /* temporary tag */
00748                 fstWriterUint64(xc->handle, destlen + 24);      /* section length */
00749                 fstWriterUint64(xc->handle, tlen);              /* uncompressed */
00750                                                                 /* compressed len is section length - 24 */
00751                 fstWriterUint64(xc->handle, xc->maxhandle);     /* maxhandle */
00752                 fstFwrite((destlen != tlen) ? dmem : tmem, destlen, 1, xc->handle);
00753                 fflush(xc->handle);
00754 
00755                 fseeko(xc->handle, fixup_offs, SEEK_SET);
00756                 fputc(FST_BL_GEOM, xc->handle);                 /* actual tag */
00757 
00758                 fseeko(xc->handle, 0, SEEK_END);                /* move file pointer to end for any section adds */
00759                 fflush(xc->handle);
00760 
00761                 free(dmem);
00762                 fstMunmap(tmem, tlen);
00763                 }
00764 
00765         if(xc->num_blackouts)
00766                 {
00767                 uint64_t cur_bl = 0;
00768                 off_t bpos, eos;
00769                 uint32_t i;
00770 
00771                 fixup_offs = ftello(xc->handle);
00772                 fputc(FST_BL_SKIP, xc->handle);                 /* temporary tag */
00773                 bpos = fixup_offs + 1;
00774                 fstWriterUint64(xc->handle, 0);                 /* section length */
00775                 fstWriterVarint(xc->handle, xc->num_blackouts);
00776 
00777                 for(i=0;i<xc->num_blackouts;i++)
00778                         {
00779                         fputc(xc->blackout_head->active, xc->handle);
00780                         fstWriterVarint(xc->handle, xc->blackout_head->tim - cur_bl);
00781                         cur_bl = xc->blackout_head->tim;
00782                         xc->blackout_curr = xc->blackout_head->next;
00783                         free(xc->blackout_head);
00784                         xc->blackout_head = xc->blackout_curr;  
00785                         }
00786 
00787                 eos = ftello(xc->handle);
00788                 fseeko(xc->handle, bpos, SEEK_SET);
00789                 fstWriterUint64(xc->handle, eos - bpos);                
00790                 fflush(xc->handle);
00791 
00792                 fseeko(xc->handle, fixup_offs, SEEK_SET);
00793                 fputc(FST_BL_BLACKOUT, xc->handle);     /* actual tag */
00794 
00795                 fseeko(xc->handle, 0, SEEK_END);        /* move file pointer to end for any section adds */
00796                 fflush(xc->handle);
00797                 }
00798 
00799         if(xc->compress_hier)
00800                 {
00801                 unsigned char *mem = malloc(FST_GZIO_LEN);
00802                 off_t hl, eos;
00803                 gzFile zhandle;
00804                 int zfd;
00805 #ifndef __MINGW32__
00806                 char *fnam = malloc(strlen(xc->filename) + 5 + 1);
00807 #endif
00808 
00809                 fixup_offs = ftello(xc->handle);
00810                 fputc(FST_BL_SKIP, xc->handle);                 /* temporary tag */
00811                 hlen = ftello(xc->handle);
00812                 fstWriterUint64(xc->handle, 0);                 /* section length */
00813                 fstWriterUint64(xc->handle, xc->hier_file_len); /* uncompressed length */
00814                 
00815                 fflush(xc->handle);
00816                 zfd = dup(fileno(xc->handle));
00817                 zhandle = gzdopen(zfd, "wb4");
00818                 if(zhandle)
00819                         {
00820                         fseeko(xc->hier_handle, 0, SEEK_SET);
00821                         for(hl = 0; hl < xc->hier_file_len; hl += FST_GZIO_LEN)
00822                                 {
00823                                 unsigned len = ((xc->hier_file_len - hl) > FST_GZIO_LEN) ? FST_GZIO_LEN : (xc->hier_file_len - hl);
00824                                 fstFread(mem, len, 1, xc->hier_handle);
00825                                 gzwrite(zhandle, mem, len);
00826                                 }
00827                         gzclose(zhandle);
00828                         }
00829                         else
00830                         {
00831                         close(zfd);
00832                         }
00833                 free(mem);
00834 
00835                 fseeko(xc->handle, 0, SEEK_END);
00836                 eos = ftello(xc->handle);
00837                 fseeko(xc->handle, hlen, SEEK_SET);
00838                 fstWriterUint64(xc->handle, eos - hlen);
00839                 fflush(xc->handle);
00840 
00841                 fseeko(xc->handle, fixup_offs, SEEK_SET);
00842                 fputc(FST_BL_HIER, xc->handle);         /* actual tag */
00843 
00844                 fseeko(xc->handle, 0, SEEK_END);        /* move file pointer to end for any section adds */
00845                 fflush(xc->handle);
00846 
00847 #ifndef __MINGW32__
00848                 sprintf(fnam, "%s.hier", xc->filename);
00849                 unlink(fnam);
00850                 free(fnam);
00851 #endif
00852                 }
00853 
00854         /* finalize out header */
00855         fseeko(xc->handle, FST_HDR_OFFS_START_TIME, SEEK_SET);
00856         fstWriterUint64(xc->handle, xc->firsttime);
00857         fstWriterUint64(xc->handle, xc->curtime);
00858         fseeko(xc->handle, FST_HDR_OFFS_NUM_SCOPES, SEEK_SET);
00859         fstWriterUint64(xc->handle, xc->numscopes);
00860         fstWriterUint64(xc->handle, xc->numsigs);
00861         fstWriterUint64(xc->handle, xc->maxhandle);
00862         fstWriterUint64(xc->handle, xc->secnum);
00863         fflush(xc->handle);
00864         
00865         if(xc->tchn_handle) { fclose(xc->tchn_handle); xc->tchn_handle = NULL; }
00866         free(xc->vchg_mem); xc->vchg_mem = NULL;
00867         if(xc->curval_handle) { fclose(xc->curval_handle); xc->curval_handle = NULL; }
00868         if(xc->valpos_handle) { fclose(xc->valpos_handle); xc->valpos_handle = NULL; }
00869         if(xc->geom_handle) { fclose(xc->geom_handle); xc->geom_handle = NULL; }
00870         if(xc->hier_handle) { fclose(xc->hier_handle); xc->hier_handle = NULL; }
00871         if(xc->handle) 
00872                 { 
00873                 if(xc->repack_on_close)
00874                         {
00875                         FILE *fp;
00876                         off_t offpnt, uclen;
00877                         int flen = strlen(xc->filename);
00878                         char *hf = calloc(1, flen + 5);
00879 
00880                         strcpy(hf, xc->filename);
00881                         strcpy(hf+flen, ".pak");
00882                         fp = fopen(hf, "wb");
00883 
00884                         if(fp)
00885                                 {
00886                                 void *dsth;
00887                                 int zfd;
00888                                 char gz_membuf[FST_GZIO_LEN];
00889 
00890                                 fseeko(xc->handle, 0, SEEK_END);
00891                                 uclen = ftello(xc->handle);
00892 
00893                                 fputc(FST_BL_ZWRAPPER, fp);
00894                                 fstWriterUint64(fp, 0);
00895                                 fstWriterUint64(fp, uclen);
00896                                 fflush(fp);
00897 
00898                                 fseeko(xc->handle, 0, SEEK_SET);
00899                                 zfd = dup(fileno(fp));
00900                                 dsth = gzdopen(zfd, "wb4");
00901                                 if(dsth)
00902                                         {
00903                                         for(offpnt = 0; offpnt < uclen; offpnt += FST_GZIO_LEN)
00904                                                 {
00905                                                 size_t this_len = ((uclen - offpnt) > FST_GZIO_LEN) ? FST_GZIO_LEN : (uclen - offpnt);
00906                                                 fstFread(gz_membuf, this_len, 1, xc->handle);
00907                                                 gzwrite(dsth, gz_membuf, this_len);
00908                                                 }
00909                                         gzclose(dsth);
00910                                         }
00911                                         else
00912                                         {
00913                                         close(zfd);
00914                                         }
00915                                 fseeko(fp, 0, SEEK_END);
00916                                 offpnt = ftello(fp);
00917                                 fseeko(fp, 1, SEEK_SET);
00918                                 fstWriterUint64(fp, offpnt - 1);
00919                                 fclose(fp);
00920                                 fclose(xc->handle); xc->handle = NULL; 
00921 
00922                                 unlink(xc->filename);
00923                                 rename(hf, xc->filename);
00924                                 }
00925                                 else
00926                                 {
00927                                 xc->repack_on_close = 0;
00928                                 fclose(xc->handle); xc->handle = NULL; 
00929                                 }
00930 
00931                         free(hf);
00932                         }
00933                         else
00934                         {
00935                         fclose(xc->handle); xc->handle = NULL; 
00936                         }
00937                 }
00938 
00939 #ifdef __MINGW32__ 
00940         {
00941         int flen = strlen(xc->filename);
00942         char *hf = calloc(1, flen + 6);
00943         strcpy(hf, xc->filename);
00944 
00945         if(xc->compress_hier)
00946                 {
00947                 strcpy(hf + flen, ".hier");
00948                 unlink(hf); /* no longer needed as a section now exists for this */
00949                 }
00950 
00951         free(hf);
00952         }
00953 #endif
00954 
00955         free(xc->filename); xc->filename = NULL;
00956         free(xc);
00957         }
00958 }

void* fstWriterCreate ( const char *  nam,
int  use_compressed_hier 
)

References fstWriterContext::compress_hier, fstWriterContext::curval_handle, fstWriterContext::filename, FST_BREAK_ADD_SIZE, FST_BREAK_SIZE, fstWriterEmitHdrBytes(), fstWriterContext::geom_handle, fstWriterContext::handle, fstWriterContext::hier_handle, fstWriterContext::is_initial_time, fstWriterContext::nan, fstWriterContext::tchn_handle, fstWriterContext::valpos_handle, fstWriterContext::vchg_alloc_siz, and fstWriterContext::vchg_mem.

00643 {
00644 struct fstWriterContext *xc = calloc(1, sizeof(struct fstWriterContext));
00645 
00646 xc->compress_hier = use_compressed_hier;
00647 
00648 if((!nam)||(!(xc->handle=fopen(nam, "w+b"))))
00649         {
00650         free(xc);
00651         xc=NULL;
00652         }
00653         else
00654         {
00655         int flen = strlen(nam);
00656         char *hf = calloc(1, flen + 6);
00657 
00658         memcpy(hf, nam, flen);
00659         strcpy(hf + flen, ".hier");
00660         xc->hier_handle = fopen(hf, "w+b");
00661 
00662         xc->geom_handle = tmpfile();    /* .geom */
00663         xc->valpos_handle = tmpfile();  /* .offs */
00664         xc->curval_handle = tmpfile();  /* .bits */
00665         xc->tchn_handle = tmpfile();    /* .tchn */
00666         xc->vchg_alloc_siz = FST_BREAK_SIZE + FST_BREAK_ADD_SIZE;
00667         xc->vchg_mem = malloc(xc->vchg_alloc_siz);
00668 
00669         free(hf);
00670         if(xc->hier_handle && xc->geom_handle && xc->valpos_handle && xc->curval_handle && xc->vchg_mem && xc->tchn_handle)
00671                 {
00672                 xc->filename = strdup(nam);
00673                 xc->is_initial_time = 1;
00674 
00675                 fstWriterEmitHdrBytes(xc);
00676                 xc->nan = strtod("NaN", NULL);
00677                 }
00678                 else
00679                 {
00680                 if(xc->hier_handle) fclose(xc->hier_handle);
00681                 if(xc->geom_handle) fclose(xc->geom_handle);
00682                 if(xc->valpos_handle) fclose(xc->valpos_handle);
00683                 if(xc->curval_handle) fclose(xc->curval_handle);
00684                 if(xc->tchn_handle) fclose(xc->tchn_handle);
00685                 free(xc->vchg_mem);
00686                 free(xc);
00687                 xc=NULL;
00688                 }
00689         }
00690 
00691 return(xc);
00692 }

fstHandle fstWriterCreateVar ( void *  ctx,
enum fstVarType  vt,
enum fstVarDir  vd,
uint32_t  len,
const char *  nam,
fstHandle  aliasHandle 
)

References fstWriterContext::curval_handle, FST_VT_VCD_REAL, FST_VT_VCD_REAL_PARAMETER, FST_VT_VCD_REALTIME, fstDestroyMmaps(), fstFwrite(), fstWriterVarint(), fstWriterContext::geom_handle, fstWriterContext::hier_file_len, fstWriterContext::hier_handle, fstWriterContext::maxhandle, fstWriterContext::maxvalpos, fstWriterContext::nan, fstWriterContext::numsigs, fstWriterContext::valpos_handle, and fstWriterContext::valpos_mem.

01493 {
01494 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
01495 int i, nlen, is_real;
01496                 
01497 if(xc && nam)
01498         {
01499         if(xc->valpos_mem)
01500                 {
01501                 fstDestroyMmaps(xc, 0);
01502                 }
01503 
01504         fputc(vt, xc->hier_handle);
01505         fputc(vd, xc->hier_handle);
01506         nlen = strlen(nam);
01507         fstFwrite(nam, nlen, 1, xc->hier_handle);
01508         fputc(0, xc->hier_handle);
01509         xc->hier_file_len += (nlen+3);
01510 
01511         if((vt == FST_VT_VCD_REAL) || (vt == FST_VT_VCD_REAL_PARAMETER) || (vt == FST_VT_VCD_REALTIME))
01512                 {
01513                 is_real = 1;
01514                 len = 8; /* recast number of bytes to that of what a double is */
01515                 }
01516                 else
01517                 {
01518                 is_real = 0;
01519                 }
01520 
01521         xc->hier_file_len += fstWriterVarint(xc->hier_handle, len);     
01522 
01523         if(aliasHandle > xc->maxhandle) aliasHandle = 0;
01524         xc->hier_file_len += fstWriterVarint(xc->hier_handle, aliasHandle);     
01525         xc->numsigs++;
01526         if(!aliasHandle)
01527                 {
01528                 uint32_t zero = 0;
01529 
01530                 fstWriterVarint(xc->geom_handle, !is_real ? len : 0); /* geom section encodes reals as zero byte */
01531 
01532                 fstFwrite(&xc->maxvalpos, sizeof(uint32_t), 1, xc->valpos_handle);
01533                 fstFwrite(&len, sizeof(uint32_t), 1, xc->valpos_handle);
01534                 fstFwrite(&zero, sizeof(uint32_t), 1, xc->valpos_handle);
01535                 fstFwrite(&zero, sizeof(uint32_t), 1, xc->valpos_handle);
01536 
01537                 if(!is_real)
01538                         {
01539                         for(i=0;i<len;i++)
01540                                 {
01541                                 fputc('x', xc->curval_handle);
01542                                 }
01543                         }
01544                         else
01545                         {
01546                         fstFwrite(&xc->nan, 8, 1, xc->curval_handle); /* initialize doubles to NaN rather than x */
01547                         }                       
01548                 
01549                 xc->maxvalpos+=len;
01550                 xc->maxhandle++;
01551                 return(xc->maxhandle);
01552                 }
01553                 else
01554                 {
01555                 return(aliasHandle);
01556                 }
01557         }
01558 
01559 return(0);
01560 }

void fstWriterEmitDumpActive ( void *  ctx,
int  enable 
)

References fstBlackoutChain::active, fstWriterContext::blackout_curr, fstWriterContext::blackout_head, fstWriterContext::curtime, fstBlackoutChain::next, fstWriterContext::num_blackouts, and fstBlackoutChain::tim.

01713 {
01714 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
01715 
01716 if(xc)
01717         {
01718         struct fstBlackoutChain *b = calloc(1, sizeof(struct fstBlackoutChain));
01719 
01720         b->tim = xc->curtime;
01721         b->active = (enable != 0);
01722 
01723         xc->num_blackouts++;
01724         if(xc->blackout_curr)
01725                 {
01726                 xc->blackout_curr->next = b;
01727                 xc->blackout_curr = b;
01728                 }
01729                 else
01730                 {
01731                 xc->blackout_head = b;
01732                 xc->blackout_curr = b;
01733                 }
01734         }
01735 }

void fstWriterEmitTimeChange ( void *  ctx,
uint64_t  tim 
)

References fstWriterContext::curtime, fstWriterContext::firsttime, FST_BREAK_SIZE, fstWriterCreateMmaps(), fstWriterEmitSectionHeader(), fstWriterFlushContext(), fstWriterVarint(), fstWriterContext::is_initial_time, fstWriterContext::maxhandle, fstWriterContext::size_limit_locked, fstWriterContext::tchn_cnt, fstWriterContext::tchn_handle, fstWriterContext::tchn_idx, fstWriterContext::valpos_mem, fstWriterContext::vc_emitted, fstWriterContext::vchg_mem, and fstWriterContext::vchg_siz.

Referenced by fstWriterClose().

01659 {
01660 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
01661 int i;
01662 int skip = 0;
01663 if(xc)
01664         {
01665         if(xc->is_initial_time)
01666                 {
01667                 if(xc->size_limit_locked)       /* this resets xc->is_initial_time to one */
01668                         {
01669                         return;
01670                         }
01671 
01672                 if(!xc->valpos_mem)
01673                         {
01674                         fstWriterCreateMmaps(xc);
01675                         }
01676 
01677                 skip = 1;
01678 
01679                 xc->firsttime = (xc->vc_emitted) ? 0: tim;
01680                 xc->curtime = 0;
01681                 xc->vchg_mem[0] = '!';
01682                 xc->vchg_siz = 1;
01683                 fstWriterEmitSectionHeader(xc);
01684                 for(i=0;i<xc->maxhandle;i++)
01685                         {
01686                         xc->valpos_mem[4*i+2] = 0; /* zero out offset val */
01687                         xc->valpos_mem[4*i+3] = 0; /* zero out last time change val */
01688                         }
01689                 xc->is_initial_time = 0;
01690                 }
01691                 else
01692                 {
01693                 if(xc->vchg_siz >= FST_BREAK_SIZE)
01694                         {
01695                         fstWriterFlushContext(xc);
01696                         xc->tchn_cnt++;
01697                         fstWriterVarint(xc->tchn_handle, xc->curtime);
01698                         }
01699                 }
01700 
01701         if(!skip)
01702                 {
01703                 xc->tchn_idx++;
01704                 }
01705         fstWriterVarint(xc->tchn_handle, tim - xc->curtime);
01706         xc->tchn_cnt++;
01707         xc->curtime = tim;
01708         }
01709 }

void fstWriterEmitValueChange ( void *  ctx,
fstHandle  handle,
const void *  val 
)

References fstWriterContext::curval_mem, FST_BREAK_ADD_SIZE, fstWriterCreateMmaps(), fstWriterUint32WithVarint32(), fstWriterContext::is_initial_time, fstWriterContext::maxhandle, fstWriterContext::tchn_idx, fstWriterContext::valpos_mem, fstWriterContext::vc_emitted, fstWriterContext::vchg_alloc_siz, fstWriterContext::vchg_mem, and fstWriterContext::vchg_siz.

Referenced by fstWriterClose().

01608 {
01609 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
01610 const unsigned char *buf = (const unsigned char *)val;
01611 uint32_t offs;
01612 int len;
01613 
01614 if((xc) && (handle <= xc->maxhandle))
01615         {
01616         uint32_t fpos;
01617         uint32_t *vm4ip;
01618 
01619         if(!xc->valpos_mem)
01620                 {
01621                 xc->vc_emitted = 1;
01622                 fstWriterCreateMmaps(xc);
01623                 }
01624 
01625         handle--; /* move starting at 1 index to starting at 0 */
01626         vm4ip = &(xc->valpos_mem[4*handle]);
01627 
01628         len  = vm4ip[1];
01629 
01630         if(!xc->is_initial_time)
01631                 {
01632                 fpos = xc->vchg_siz;
01633 
01634                 if((fpos + len + 10) > xc->vchg_alloc_siz)
01635                         {
01636                         xc->vchg_alloc_siz += FST_BREAK_ADD_SIZE;
01637                         xc->vchg_mem = realloc(xc->vchg_mem, xc->vchg_alloc_siz);
01638                         if(!xc->vchg_mem)
01639                                 {
01640                                 fprintf(stderr, "FATAL ERROR, could not realloc() in fstWriterEmitValueChange, exiting.\n");
01641                                 exit(255); 
01642                                 }
01643                         }
01644 
01645                 xc->vchg_siz += fstWriterUint32WithVarint32(xc, &vm4ip[2], xc->tchn_idx - vm4ip[3], buf, len); /* do one fwrite op only */
01646                 vm4ip[3] = xc->tchn_idx;
01647                 vm4ip[2] = fpos;
01648                 }
01649                 else
01650                 {
01651                 offs = vm4ip[0];
01652                 memcpy(xc->curval_mem + offs, buf, len);
01653                 }
01654         }
01655 }

void fstWriterFlushContext ( void *  ctx  ) 

References fstWriterContext::already_in_flush, fstWriterContext::curtime, fstWriterContext::curval_mem, fstWriterContext::dump_size_limit, fastlz_compress(), fstWriterContext::fastpack, FST_BL_VCDATA, FST_RCV_D, FST_RCV_H, FST_RCV_L, FST_RCV_U, FST_RCV_W, FST_RCV_X, FST_RCV_Z, fstCopyVarint32ToLeft(), fstFtruncate(), fstFwrite(), fstGetUint32(), fstGetVarint32(), fstGetVarint32Length(), fstMmap, fstMunmap, fstWriterEmitSectionHeader(), fstWriterUint64(), fstWriterVarint(), fstWriterContext::handle, fstWriterContext::is_initial_time, fstWriterContext::maxhandle, fstWriterContext::secnum, fstWriterContext::section_header_only, fstWriterContext::section_header_truncpos, fstWriterContext::section_start, fstWriterContext::size_limit_locked, fstWriterContext::skip_writing_section_hdr, fstWriterContext::tchn_cnt, fstWriterContext::tchn_handle, fstWriterContext::tchn_idx, fstWriterContext::valpos_mem, fstWriterContext::vchg_mem, and fstWriterContext::vchg_siz.

Referenced by fstWriterClose(), and fstWriterEmitTimeChange().

01012 {
01013 #ifdef FST_DEBUG
01014 int cnt = 0;
01015 #endif
01016 int i;
01017 unsigned char *vchg_mem;
01018 FILE *f;
01019 off_t fpos, indxpos, endpos;
01020 uint32_t prevpos;
01021 int zerocnt;
01022 unsigned char *scratchpad;
01023 unsigned char *scratchpnt;
01024 unsigned char *tmem;
01025 off_t tlen;
01026 off_t unc_memreq = 0; /* for reader */
01027 unsigned char *packmem;
01028 unsigned int packmemlen;
01029 uint32_t *vm4ip;
01030 
01031 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
01032 
01033 if((!xc)||(xc->vchg_siz <= 1)||(xc->already_in_flush)) return;
01034 xc->already_in_flush = 1; /* should really do this with a semaphore */
01035 
01036 xc->section_header_only = 0;
01037 scratchpad = malloc(xc->vchg_siz);
01038 
01039 vchg_mem = xc->vchg_mem;
01040 
01041 f = xc->handle;
01042 fstWriterVarint(f, xc->maxhandle);      /* emit current number of handles */
01043 fputc(xc->fastpack ? 'F' : 'Z', f);
01044 fpos = 1;
01045 
01046 packmemlen = 1024;                      /* maintain a running "longest" allocation to */
01047 packmem = malloc(packmemlen);           /* prevent continual malloc...free every loop iter */
01048 
01049 for(i=0;i<xc->maxhandle;i++)
01050         {
01051         vm4ip = &(xc->valpos_mem[4*i]);
01052 
01053         if(vm4ip[2]) 
01054                 {
01055                 uint32_t offs = vm4ip[2];
01056                 uint32_t next_offs;
01057                 int wrlen;
01058 
01059                 vm4ip[2] = fpos;
01060 
01061                 scratchpnt = scratchpad + xc->vchg_siz;         /* build this buffer backwards */
01062                 if(vm4ip[1] == 1)
01063                         {
01064                         wrlen = fstGetVarint32Length(vchg_mem + offs + 4); /* used to advance and determine wrlen */
01065                         xc->curval_mem[vm4ip[0]] = vchg_mem[offs + 4 + wrlen]; /* checkpoint variable */
01066 
01067                         while(offs)
01068                                 {
01069                                 unsigned char val;
01070                                 uint32_t time_delta, rcv;
01071                                 next_offs = fstGetUint32(vchg_mem + offs);
01072                                 offs += 4;   
01073                         
01074                                 time_delta = fstGetVarint32(vchg_mem + offs, &wrlen);
01075                                 val = vchg_mem[offs+wrlen];
01076                                 offs = next_offs;
01077 
01078                                 switch(val)
01079                                         {
01080                                         case '0':
01081                                         case '1':               rcv = ((val&1)<<1) | (time_delta<<2);
01082                                                                 break; /* pack more delta bits in for 0/1 vchs */
01083         
01084                                         case 'x': case 'X':     rcv = FST_RCV_X | (time_delta<<4); break;
01085                                         case 'z': case 'Z':     rcv = FST_RCV_Z | (time_delta<<4); break;
01086                                         case 'h': case 'H':     rcv = FST_RCV_H | (time_delta<<4); break;
01087                                         case 'u': case 'U':     rcv = FST_RCV_U | (time_delta<<4); break;
01088                                         case 'w': case 'W':     rcv = FST_RCV_W | (time_delta<<4); break;
01089                                         case 'l': case 'L':     rcv = FST_RCV_L | (time_delta<<4); break;
01090                                         default:                rcv = FST_RCV_D | (time_delta<<4); break;
01091                                         }
01092                 
01093                                 scratchpnt = fstCopyVarint32ToLeft(scratchpnt, rcv);
01094                                 }
01095                         }
01096                         else
01097                         {
01098                         wrlen = fstGetVarint32Length(vchg_mem + offs + 4); /* used to advance and determine wrlen */
01099                         memcpy(xc->curval_mem + vm4ip[0], vchg_mem + offs + 4 + wrlen, vm4ip[1]); /* checkpoint variable */
01100 
01101                         while(offs)
01102                                 {
01103                                 int idx;
01104                                 char is_binary = 1;
01105                                 unsigned char *pnt;
01106                                 uint32_t time_delta;
01107 
01108                                 next_offs = fstGetUint32(vchg_mem + offs);
01109                                 offs += 4;
01110 
01111                                 time_delta = fstGetVarint32(vchg_mem + offs, &wrlen);
01112 
01113                                 pnt = vchg_mem+offs+wrlen;
01114                                 offs = next_offs;
01115 
01116                                 for(idx=0;idx<vm4ip[1];idx++)
01117                                         {
01118                                         if((pnt[idx] == '0') || (pnt[idx] == '1'))
01119                                                 {
01120                                                 continue;
01121                                                 }
01122                                                 else
01123                                                 {
01124                                                 is_binary = 0;
01125                                                 break;
01126                                                 }
01127                                         }
01128 
01129                                 if(is_binary)
01130                                         {
01131                                         unsigned char acc = 0;
01132                                         int shift = 7 - ((vm4ip[1]-1) & 7);
01133                                         for(idx=vm4ip[1]-1;idx>=0;idx--)
01134                                                 {
01135                                                 acc |= (pnt[idx] & 1) << shift;
01136                                                 shift++;
01137                                                 if(shift == 8)
01138                                                         {
01139                                                         *(--scratchpnt) = acc;
01140                                                         shift = 0;
01141                                                         acc = 0;
01142                                                         }                                               
01143                                                 }                                       
01144 
01145                                         scratchpnt = fstCopyVarint32ToLeft(scratchpnt, (time_delta << 1));
01146                                         }
01147                                         else
01148                                         {
01149                                         scratchpnt -= vm4ip[1];
01150                                         memcpy(scratchpnt, pnt, vm4ip[1]);
01151 
01152                                         scratchpnt = fstCopyVarint32ToLeft(scratchpnt, (time_delta << 1) | 1);
01153                                         }
01154                                 }
01155                         }
01156 
01157                 wrlen = scratchpad + xc->vchg_siz - scratchpnt;
01158                 unc_memreq += wrlen;
01159                 if(wrlen > 32)
01160                         {
01161                         unsigned long destlen = wrlen;
01162                         unsigned char *dmem;
01163                         int rc;
01164 
01165                         if(!xc->fastpack)
01166                                 {
01167                                 if(wrlen <= packmemlen)
01168                                         {
01169                                         dmem = packmem;
01170                                         }
01171                                         else
01172                                         {
01173                                         free(packmem);
01174                                         dmem = packmem = malloc(packmemlen = wrlen);
01175                                         }
01176 
01177                                 rc = compress2(dmem, &destlen, scratchpnt, wrlen, 4);
01178                                 if(rc == Z_OK)
01179                                         {
01180                                         fpos += fstWriterVarint(f, wrlen);
01181                                         fpos += destlen;
01182                                         fstFwrite(dmem, destlen, 1, f);
01183                                         }
01184                                         else
01185                                         {
01186                                         fpos += fstWriterVarint(f, 0);
01187                                         fpos += wrlen;
01188                                         fstFwrite(scratchpnt, wrlen, 1, f);
01189                                         }
01190                                 }
01191                                 else
01192                                 {
01193                                 if(((wrlen * 2) + 2) <= packmemlen)
01194                                         {
01195                                         dmem = packmem;
01196                                         }
01197                                         else
01198                                         {
01199                                         free(packmem);
01200                                         dmem = packmem = malloc(packmemlen = (wrlen * 2) + 2);
01201                                         }
01202 
01203                                 rc = fastlz_compress(scratchpnt, wrlen, dmem);
01204                                 if(rc < destlen)
01205                                         {
01206                                         fpos += fstWriterVarint(f, wrlen);
01207                                         fpos += rc;
01208                                         fstFwrite(dmem, rc, 1, f);
01209                                         }
01210                                         else
01211                                         {
01212                                         fpos += fstWriterVarint(f, 0);
01213                                         fpos += wrlen;
01214                                         fstFwrite(scratchpnt, wrlen, 1, f);
01215                                         }
01216                                 }
01217                         }
01218                         else
01219                         {
01220                         fpos += fstWriterVarint(f, 0);
01221                         fpos += wrlen;
01222                         fstFwrite(scratchpnt, wrlen, 1, f);
01223                         }
01224 
01225                 vm4ip[3] = 0;
01226 #ifdef FST_DEBUG
01227                 cnt++;
01228 #endif
01229                 }
01230         }
01231 
01232 free(packmem); packmem = NULL; packmemlen = 0;
01233 
01234 prevpos = 0; zerocnt = 0;
01235 free(scratchpad); scratchpad = NULL;
01236 
01237 indxpos = ftello(f);
01238 xc->secnum++;
01239 
01240 for(i=0;i<xc->maxhandle;i++)
01241         {
01242         vm4ip = &(xc->valpos_mem[4*i]);
01243 
01244         if(vm4ip[2])
01245                 {
01246                 if(zerocnt)
01247                         {
01248                         fpos += fstWriterVarint(f, (zerocnt << 1));
01249                         zerocnt = 0;
01250                         }
01251 
01252                 fpos += fstWriterVarint(f, ((vm4ip[2] - prevpos) << 1) | 1);
01253                 prevpos = vm4ip[2];
01254                 vm4ip[2] = 0;
01255                 vm4ip[3] = 0; /* clear out tchn idx */
01256                 }
01257                 else
01258                 {
01259                 zerocnt++;              
01260                 }
01261         }
01262 if(zerocnt)
01263         {
01264         fpos += fstWriterVarint(f, (zerocnt << 1));
01265         }
01266 #ifdef FST_DEBUG
01267 printf("value chains: %d\n", cnt);
01268 #endif
01269 
01270 xc->vchg_mem[0] = '!';
01271 xc->vchg_siz = 1;
01272 
01273 endpos = ftello(xc->handle);
01274 fstWriterUint64(xc->handle, endpos-indxpos);            /* write delta index position at very end of block */
01275 
01276 /*emit time changes for block */
01277 fflush(xc->tchn_handle);
01278 tlen = ftello(xc->tchn_handle);
01279 fseeko(xc->tchn_handle, 0, SEEK_SET);
01280 
01281 tmem = fstMmap(NULL, tlen, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->tchn_handle), 0);
01282 if(tmem)
01283         {
01284         unsigned long destlen = tlen;
01285         unsigned char *dmem = malloc(destlen);
01286         int rc = compress2(dmem, &destlen, tmem, tlen, 9);
01287 
01288         if((rc == Z_OK) && (destlen < tlen))
01289                 {
01290                 fstFwrite(dmem, destlen, 1, xc->handle);
01291                 }
01292                 else /* comparison between compressed / decompressed len tells if compressed */
01293                 {
01294                 fstFwrite(tmem, tlen, 1, xc->handle);
01295                 destlen = tlen;
01296                 }
01297         free(dmem);
01298         fstMunmap(tmem, tlen);
01299         fstWriterUint64(xc->handle, tlen);              /* uncompressed */
01300         fstWriterUint64(xc->handle, destlen);           /* compressed */
01301         fstWriterUint64(xc->handle, xc->tchn_cnt);      /* number of time items */
01302         }
01303 
01304 xc->tchn_cnt = xc->tchn_idx = 0;
01305 fseeko(xc->tchn_handle, 0, SEEK_SET);
01306 fstFtruncate(fileno(xc->tchn_handle), 0);
01307 
01308 /* write block trailer */
01309 endpos = ftello(xc->handle);
01310 fseeko(xc->handle, xc->section_start, SEEK_SET);
01311 fstWriterUint64(xc->handle, endpos - xc->section_start);        /* write block length */
01312 fseeko(xc->handle, 8, SEEK_CUR);                                /* skip begin time */
01313 fstWriterUint64(xc->handle, xc->curtime);                       /* write end time for section */
01314 fstWriterUint64(xc->handle, unc_memreq);                        /* amount of buffer memory required in reader for full traversal */
01315 fflush(xc->handle);
01316 
01317 fseeko(xc->handle, xc->section_start-1, SEEK_SET);              /* write out FST_BL_VCDATA over FST_BL_SKIP */
01318 fputc(FST_BL_VCDATA, xc->handle);
01319 fflush(xc->handle);
01320 
01321 fseeko(xc->handle, endpos, SEEK_SET);                           /* seek to end of file */
01322 
01323 xc->section_header_truncpos = endpos;                           /* cache in case of need to truncate */
01324 if(xc->dump_size_limit)
01325         {
01326         if(endpos >= xc->dump_size_limit)
01327                 {
01328                 xc->skip_writing_section_hdr = 1;
01329                 xc->size_limit_locked = 1;
01330                 xc->is_initial_time = 1; /* to trick emit value and emit time change */
01331 #ifdef FST_DEBUG
01332                 printf("<< dump file size limit reached, stopping dumping >>\n");
01333 #endif
01334                 }
01335         }
01336 
01337 if(!xc->skip_writing_section_hdr)
01338         {
01339         fstWriterEmitSectionHeader(xc);                         /* emit next section header */
01340         }
01341 fflush(xc->handle);
01342 
01343 xc->already_in_flush = 0;
01344 }

int fstWriterGetDumpSizeLimitReached ( void *  ctx  ) 

References fstWriterContext::size_limit_locked.

01477 {
01478 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
01479 if(xc)
01480         {
01481         return(xc->size_limit_locked != 0);
01482         }
01483 
01484 return(0);
01485 }

void fstWriterSetDate ( void *  ctx,
const char *  dat 
)

References FST_HDR_DATE_SIZE, FST_HDR_OFFS_DATE, fstFwrite(), and fstWriterContext::handle.

01351 {
01352 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
01353 if(xc)
01354         {
01355         char s[FST_HDR_DATE_SIZE];
01356         off_t fpos = ftello(xc->handle);
01357         int len = strlen(dat);
01358 
01359         fseeko(xc->handle, FST_HDR_OFFS_DATE, SEEK_SET);
01360         memset(s, 0, FST_HDR_DATE_SIZE);
01361         memcpy(s, dat, (len < FST_HDR_DATE_SIZE) ? len : FST_HDR_DATE_SIZE);
01362         fstFwrite(s, FST_HDR_DATE_SIZE, 1, xc->handle);
01363         fflush(xc->handle);
01364         fseeko(xc->handle, fpos, SEEK_SET);
01365         }
01366 }

void fstWriterSetDumpSizeLimit ( void *  ctx,
uint64_t  numbytes 
)

References fstWriterContext::dump_size_limit.

01467 {
01468 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
01469 if(xc)
01470         {
01471         xc->dump_size_limit = numbytes;
01472         }
01473 }

void fstWriterSetPackType ( void *  ctx,
int  typ 
)

References fstWriterContext::fastpack.

01447 {
01448 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
01449 if(xc)
01450         {
01451         xc->fastpack = (typ != 0);
01452         }
01453 }

void fstWriterSetRepackOnClose ( void *  ctx,
int  enable 
)

References fstWriterContext::repack_on_close.

01457 {
01458 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
01459 if(xc)
01460         {
01461         xc->repack_on_close = (enable != 0);
01462         }
01463 }

void fstWriterSetScope ( void *  ctx,
enum fstScopeType  scopetype,
const char *  scopename,
const char *  scopecomp 
)

References FST_ST_MAX, FST_ST_VCD_MODULE, FST_ST_VCD_SCOPE, fstWriterContext::hier_file_len, fstWriterContext::hier_handle, and fstWriterContext::numscopes.

01565 {
01566 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
01567 
01568 if(xc && scopename)
01569         {
01570         fputc(FST_ST_VCD_SCOPE, xc->hier_handle);
01571         if((scopetype < FST_ST_VCD_MODULE) || (scopetype > FST_ST_MAX)) { scopetype = FST_ST_VCD_MODULE; }
01572         fputc(scopetype, xc->hier_handle);
01573         fprintf(xc->hier_handle, "%s%c%s%c",
01574                 scopename ? scopename : "", 0,
01575                 scopecomp ? scopecomp : "", 0);
01576         
01577         if(scopename)
01578                 {
01579                 xc->hier_file_len += strlen(scopename);
01580                 }
01581         if(scopecomp)
01582                 {
01583                 xc->hier_file_len += strlen(scopecomp);
01584                 }
01585 
01586         xc->hier_file_len += 4; /* FST_ST_VCD_SCOPE + scopetype + two string terminating zeros */
01587         xc->numscopes++;
01588         }
01589 }

void fstWriterSetTimescale ( void *  ctx,
int  ts 
)

References FST_HDR_OFFS_TIMESCALE, and fstWriterContext::handle.

Referenced by fstWriterSetTimescaleFromString().

01389 {
01390 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
01391 if(xc)
01392         {
01393         off_t fpos = ftello(xc->handle);
01394         fseeko(xc->handle, FST_HDR_OFFS_TIMESCALE, SEEK_SET);
01395         fputc(ts & 255, xc->handle);
01396         fflush(xc->handle);
01397         fseeko(xc->handle, fpos, SEEK_SET);
01398         }
01399 }

void fstWriterSetTimescaleFromString ( void *  ctx,
const char *  s 
)

References fstWriterSetTimescale().

01403 {
01404 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
01405 if(xc && s)
01406         {
01407         int mat = 0;
01408         int seconds_exp = -9;
01409         int tv = atoi(s);
01410         const char *pnt = s;
01411 
01412         while(*pnt)
01413                 {
01414                 switch(*pnt)
01415                         {
01416                         case 'm': seconds_exp = -3; mat = 1; break;
01417                         case 'u': seconds_exp = -6; mat = 1; break;
01418                         case 'n': seconds_exp = -9; mat = 1; break;
01419                         case 'p': seconds_exp = -12; mat = 1; break;
01420                         case 'f': seconds_exp = -15; mat = 1; break;
01421                         case 'a': seconds_exp = -18; mat = 1; break;
01422                         case 'z': seconds_exp = -21; mat = 1; break;
01423                         case 's': seconds_exp = -0; mat = 1; break;
01424                         default: break;
01425                         }
01426 
01427                 if(mat) break;
01428                 pnt++;
01429                 }
01430 
01431         if(tv == 10)
01432                 {
01433                 seconds_exp++;
01434                 } 
01435         else
01436         if(tv == 100)
01437                 {
01438                 seconds_exp+=2;
01439                 }
01440                               
01441         fstWriterSetTimescale(ctx, seconds_exp);
01442         }
01443 }

void fstWriterSetUpscope ( void *  ctx  ) 

References FST_ST_VCD_UPSCOPE, fstWriterContext::hier_file_len, and fstWriterContext::hier_handle.

01593 {
01594 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
01595 
01596 if(xc)
01597         {
01598         fputc(FST_ST_VCD_UPSCOPE, xc->hier_handle);
01599         xc->hier_file_len++;
01600         }
01601 }

void fstWriterSetVersion ( void *  ctx,
const char *  vers 
)

References FST_HDR_OFFS_SIM_VERSION, FST_HDR_SIM_VERSION_SIZE, fstFwrite(), and fstWriterContext::handle.

01370 {
01371 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
01372 if(xc && vers)
01373         {
01374         char s[FST_HDR_SIM_VERSION_SIZE];
01375         off_t fpos = ftello(xc->handle);
01376         int len = strlen(vers);
01377 
01378         fseeko(xc->handle, FST_HDR_OFFS_SIM_VERSION, SEEK_SET);
01379         memset(s, 0, FST_HDR_SIM_VERSION_SIZE);
01380         memcpy(s, vers, (len < FST_HDR_SIM_VERSION_SIZE) ? len : FST_HDR_SIM_VERSION_SIZE);
01381         fstFwrite(s, FST_HDR_SIM_VERSION_SIZE, 1, xc->handle);
01382         fflush(xc->handle);
01383         fseeko(xc->handle, fpos, SEEK_SET);
01384         }
01385 }

Generated on Sun Nov 21 00:55:39 2010 for Covered by  doxygen 1.6.3