1 /*
2  * Copyright (c) Tony Bybell 1999-2017.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  */
9 
10 
11 /*
12  * vcd.c 			23jan99ajb
13  * evcd parts 			29jun99ajb
14  * profiler optimizations 	15jul99ajb
15  * more profiler optimizations	25jan00ajb
16  * finsim parameter fix		26jan00ajb
17  * vector rechaining code	03apr00ajb
18  * multiple var section code	06apr00ajb
19  * fix for duplicate nets	19dec00ajb
20  * support for alt hier seps	23dec00ajb
21  * fix for rcs identifiers	16jan01ajb
22  * coredump fix for bad VCD	04apr02ajb
23  * min/maxid speedup            27feb03ajb
24  * bugfix on min/maxid speedup  06jul03ajb
25  * escaped hier modification    20feb06ajb
26  * added real_parameter vartype 04aug06ajb
27  * recoder using vlists         17aug06ajb
28  * code cleanup                 04sep06ajb
29  * added in/out port vartype    31jan07ajb
30  * use gperf for port vartypes  19feb07ajb
31  * MTI SV implicit-var fix      05apr07ajb
32  * MTI SV len=0 is real var     05apr07ajb
33  * VCD fastloading		05mar09ajb
34  * Backtracking fix             16oct18ajb
35  */
36 #include <config.h>
37 #include "globals.h"
38 #include "vcd.h"
39 #include "vlist.h"
40 #include "lx2.h"
41 #include "hierpack.h"
42 
43 /**/
44 
malform_eof_fix(void)45 static void malform_eof_fix(void)
46 {
47 if(feof(GLOBALS->vcd_handle_vcd_recoder_c_2))
48 	{
49         memset(GLOBALS->vcdbuf_vcd_recoder_c_3, ' ', VCD_BSIZ);
50         GLOBALS->vst_vcd_recoder_c_3=GLOBALS->vend_vcd_recoder_c_3;
51         }
52 }
53 
54 /**/
55 
vlist_packer_emit_uv64(struct vlist_packer_t ** vl,guint64 v)56 static void vlist_packer_emit_uv64(struct vlist_packer_t **vl, guint64 v)
57 {
58 guint64 nxt;
59 
60 while((nxt = v>>7))
61         {
62 	vlist_packer_alloc(*vl, v&0x7f);
63         v = nxt;
64         }
65 
66 vlist_packer_alloc(*vl, (v&0x7f) | 0x80);
67 }
68 
69 
vlist_packer_emit_utt(struct vlist_packer_t ** vl,UTimeType v)70 static void vlist_packer_emit_utt(struct vlist_packer_t **vl, UTimeType v)
71 {
72 UTimeType nxt;
73 
74 while((nxt = v>>7))
75         {
76 	vlist_packer_alloc(*vl, v&0x7f);
77         v = nxt;
78         }
79 
80 vlist_packer_alloc(*vl, (v&0x7f) | 0x80);
81 }
82 
83 
vlist_packer_emit_uv32(struct vlist_packer_t ** vl,unsigned int v)84 static void vlist_packer_emit_uv32(struct vlist_packer_t **vl, unsigned int v)
85 {
86 unsigned int nxt;
87 
88 while((nxt = v>>7))
89         {
90 	vlist_packer_alloc(*vl, v&0x7f);
91         v = nxt;
92         }
93 
94 vlist_packer_alloc(*vl, (v&0x7f) | 0x80);
95 }
96 
97 
vlist_packer_emit_string(struct vlist_packer_t ** vl,char * s)98 static void vlist_packer_emit_string(struct vlist_packer_t **vl, char *s)
99 {
100 while(*s)
101 	{
102 	vlist_packer_alloc(*vl, *s);
103 	s++;
104 	}
105 vlist_packer_alloc(*vl, 0);
106 }
107 
vlist_packer_emit_mvl9_string(struct vlist_packer_t ** vl,char * s)108 static void vlist_packer_emit_mvl9_string(struct vlist_packer_t **vl, char *s)
109 {
110 unsigned int recoded_bit;
111 unsigned char which = 0;
112 unsigned char accum = 0;
113 
114 while(*s)
115 	{
116 	switch(*s)
117 	        {
118 	        case '0':		recoded_bit = AN_0; break;
119 	        case '1':		recoded_bit = AN_1; break;
120 	        case 'x': case 'X':	recoded_bit = AN_X; break;
121 	        case 'z': case 'Z':	recoded_bit = AN_Z; break;
122 	        case 'h': case 'H':	recoded_bit = AN_H; break;
123 	        case 'u': case 'U':	recoded_bit = AN_U; break;
124 	        case 'w': case 'W':     recoded_bit = AN_W; break;
125 	        case 'l': case 'L':	recoded_bit = AN_L; break;
126 		default:		recoded_bit = AN_DASH; break;
127 		}
128 
129 	if(!which)
130 		{
131 		accum = (recoded_bit << 4);
132 		which = 1;
133 		}
134 		else
135 		{
136 		accum |= recoded_bit;
137 		vlist_packer_alloc(*vl, accum);
138 		which = accum = 0;
139 		}
140 	s++;
141 	}
142 
143 recoded_bit = AN_MSK; /* XXX : this is assumed it is going to remain a 4 bit max quantity! */
144 if(!which)
145 	{
146         accum = (recoded_bit << 4);
147         }
148         else
149         {
150         accum |= recoded_bit;
151         }
152 
153 vlist_packer_alloc(*vl, accum);
154 }
155 
156 /**/
157 
vlist_emit_uv32(struct vlist_t ** vl,unsigned int v)158 static void vlist_emit_uv32(struct vlist_t **vl, unsigned int v)
159 {
160 unsigned int nxt;
161 char *pnt;
162 
163 if(GLOBALS->vlist_prepack) { vlist_packer_emit_uv32((struct vlist_packer_t **)vl, v); return; }
164 
165 while((nxt = v>>7))
166         {
167 	pnt = vlist_alloc(vl, 1);
168         *pnt = (v&0x7f);
169         v = nxt;
170         }
171 
172 pnt = vlist_alloc(vl, 1);
173 *pnt = (v&0x7f) | 0x80;
174 }
175 
176 
vlist_emit_string(struct vlist_t ** vl,char * s)177 static void vlist_emit_string(struct vlist_t **vl, char *s)
178 {
179 char *pnt;
180 
181 if(GLOBALS->vlist_prepack) { vlist_packer_emit_string((struct vlist_packer_t **)vl, s); return; }
182 
183 while(*s)
184 	{
185 	pnt = vlist_alloc(vl, 1);
186 	*pnt = *s;
187 	s++;
188 	}
189 pnt = vlist_alloc(vl, 1);
190 *pnt = 0;
191 }
192 
vlist_emit_mvl9_string(struct vlist_t ** vl,char * s)193 static void vlist_emit_mvl9_string(struct vlist_t **vl, char *s)
194 {
195 char *pnt;
196 unsigned int recoded_bit;
197 unsigned char which;
198 unsigned char accum;
199 
200 if(GLOBALS->vlist_prepack) { vlist_packer_emit_mvl9_string((struct vlist_packer_t **)vl, s); return; }
201 
202 which = accum = 0;
203 
204 while(*s)
205 	{
206 	switch(*s)
207 	        {
208 	        case '0':		recoded_bit = AN_0; break;
209 	        case '1':		recoded_bit = AN_1; break;
210 	        case 'x': case 'X':	recoded_bit = AN_X; break;
211 	        case 'z': case 'Z':	recoded_bit = AN_Z; break;
212 	        case 'h': case 'H':	recoded_bit = AN_H; break;
213 	        case 'u': case 'U':	recoded_bit = AN_U; break;
214 	        case 'w': case 'W':     recoded_bit = AN_W; break;
215 	        case 'l': case 'L':	recoded_bit = AN_L; break;
216 		default:		recoded_bit = AN_DASH; break;
217 		}
218 
219 	if(!which)
220 		{
221 		accum = (recoded_bit << 4);
222 		which = 1;
223 		}
224 		else
225 		{
226 		accum |= recoded_bit;
227 		pnt = vlist_alloc(vl, 1);
228 		*pnt = accum;
229 		which = accum = 0;
230 		}
231 	s++;
232 	}
233 
234 recoded_bit = AN_MSK; /* XXX : this is assumed it is going to remain a 4 bit max quantity! */
235 if(!which)
236 	{
237         accum = (recoded_bit << 4);
238         }
239         else
240         {
241         accum |= recoded_bit;
242         }
243 
244 pnt = vlist_alloc(vl, 1);
245 *pnt = accum;
246 }
247 
248 /**/
249 
write_fastload_time_section(void)250 static void write_fastload_time_section(void)
251 {
252 struct vlist_t *vlist;
253 struct vlist_packer_t *vlist_p;
254 
255 /* emit blackout regions */
256 if(GLOBALS->blackout_regions)
257 	{
258 	struct blackout_region_t *bt = GLOBALS->blackout_regions;
259 	unsigned int bcnt = 0;
260 	while(bt)
261 		{
262 		bcnt++;
263 		bt = bt->next;
264 		}
265 
266 	vlist_packer_emit_uv32((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, bcnt);
267 
268 	bt = GLOBALS->blackout_regions;
269 	while(bt)
270 		{
271 		vlist_packer_emit_utt((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, bt->bstart);
272 		vlist_packer_emit_utt((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, bt->bend);
273 		bt = bt->next;
274 		}
275 	}
276 	else
277 	{
278 	vlist_packer_emit_uv32((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, 0);
279 	}
280 
281 vlist_p = (struct vlist_packer_t *)GLOBALS->time_vlist_vcd_recoder_write;
282 vlist_packer_finalize(vlist_p);
283 vlist = vlist_p->v;
284 free_2(vlist_p);
285 GLOBALS->time_vlist_vcd_recoder_write = vlist;
286 vlist_freeze(&GLOBALS->time_vlist_vcd_recoder_write);
287 }
288 
289 #ifdef HAVE_SYS_STAT_H
write_fastload_header(struct stat * mystat,unsigned int finalize_cnt)290 static void write_fastload_header(struct stat *mystat, unsigned int finalize_cnt)
291 #else
292 static void write_fastload_header(unsigned int finalize_cnt)
293 #endif
294 {
295 /*
296 write out the trailer information for vcd fastload...
297 
298 vcd file size
299 vcd last modification time
300 number of finalize values
301 number of variable-length integer values in the time table (GLOBALS->time_vlist_count_vcd_recoder_c_1)
302 GLOBALS->time_vlist_vcd_recoder_write value
303 deltas from GLOBALS->time_vlist_vcd_recoder_write and on though stepping through list generated by vlist_emit_finalize()
304 */
305 
306 struct vlist_packer_t *vlist_p = vlist_packer_create();
307 struct vlist_t *vlist_summary_index;
308 
309 struct vcdsymbol *v = GLOBALS->vcdsymroot_vcd_recoder_c_3;
310 guint64 val = (guint64)(uintptr_t)GLOBALS->time_vlist_vcd_recoder_write;
311 guint64 nval;
312 char buf[33];
313 char *pnt;
314 
315 memset(buf, 0, sizeof(buf)); /* scan-build */
316 
317 #ifdef HAVE_SYS_STAT_H
318 vlist_packer_emit_uv64(&vlist_p, (guint64)mystat->st_size);
319 vlist_packer_emit_uv64(&vlist_p, (guint64)mystat->st_mtime);
320 #else
321 vlist_packer_emit_uv64(&vlist_p, (guint64)0);
322 vlist_packer_emit_uv64(&vlist_p, (guint64)0);
323 #endif
324 
325 vlist_packer_emit_uv32(&vlist_p, finalize_cnt);
326 vlist_packer_emit_uv64(&vlist_p, GLOBALS->time_vlist_count_vcd_recoder_c_1);
327 
328 vlist_packer_emit_uv64(&vlist_p, val);
329 val = 0;
330 while(v)
331 	{
332 	nptr n = v->narray[0];
333 	nval = (guint64)(uintptr_t)n->mv.mvlfac_vlist;
334 
335 	vlist_packer_emit_uv64(&vlist_p, nval - val);
336 	val = nval;
337 
338 	v = v->next;
339 	}
340 
341 vlist_packer_finalize(vlist_p);
342 vlist_summary_index = vlist_p->v;
343 free_2(vlist_p);
344 GLOBALS->time_vlist_vcd_recoder_write = vlist_summary_index;
345 vlist_freeze(&vlist_summary_index);
346 
347 pnt = buf;
348 val = (guint64)(uintptr_t)vlist_summary_index;
349 while((nval = val>>7))
350 	{
351 	*(pnt++) = (val&0x7f);
352 	val = nval;
353 	}
354 *(pnt++) = ((val&0x7f) | 0x80);
355 do
356 	{
357 	pnt--;
358 	fputc((unsigned char)*pnt, GLOBALS->vlist_handle);
359 	} while(pnt != buf);
360 
361 fflush(GLOBALS->vlist_handle);
362 }
363 
364 
read_fastload_body(void)365 static int read_fastload_body(void)
366 {
367 char *depacked = GLOBALS->fastload_depacked;
368 char *pnt = GLOBALS->fastload_current;
369 int rc = 0;
370 guint64 v = 0, vprev = 0;
371 int shamt = 0;
372 /* unsigned int num_finalize; */ /* scan-build */
373 unsigned int num_in_time_table, num_blackout_regions;
374 guint64 time_vlist_vcd_recoder_write;
375 struct vcdsymbol *vs;
376 struct vlist_t *vl;
377 unsigned int list_size;
378 unsigned int i;
379 struct blackout_region_t *bt_head = NULL, *bt_curr = NULL;
380 
381 v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
382 /* num_finalize = v; */ /* scan-build */
383 
384 v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
385 GLOBALS->time_vlist_count_vcd_recoder_c_1 = num_in_time_table = v;
386 
387 v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
388 time_vlist_vcd_recoder_write = v;
389 
390 vs=GLOBALS->vcdsymroot_vcd_recoder_c_3;
391 while(vs)
392         {
393         nptr n = vs->narray[0];
394 
395 	v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
396 	v += vprev;
397 	vprev = v;
398 
399         n->mv.mvlfac_vlist = (struct vlist_t *)(intptr_t)(v);
400 	vs = vs->next;
401 	}
402 
403 vlist_packer_decompress_destroy((char *)depacked);
404 GLOBALS->fastload_depacked = NULL;
405 GLOBALS->fastload_current = NULL;
406 
407 /* now create the time table */
408 vl = (struct vlist_t *)(intptr_t)time_vlist_vcd_recoder_write;
409 vlist_uncompress(&vl);
410 depacked = pnt = (char *)vlist_packer_decompress(vl, &list_size);
411 vlist_destroy(vl);
412 
413 vprev = 0;
414 for(i=0;i<num_in_time_table;i++)
415 	{
416 	TimeType tim;
417 	TimeType *tt;
418 
419 	v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
420 
421 	v += vprev;
422 	vprev = v;
423 
424 	tt = vlist_alloc(&GLOBALS->time_vlist_vcd_recoder_c_1, 0);
425         *tt = tim = (TimeType)v;
426 
427 	if(!i)
428 		{
429 		GLOBALS->start_time_vcd_recoder_c_3=tim;
430 		}
431 
432 	GLOBALS->current_time_vcd_recoder_c_3=GLOBALS->end_time_vcd_recoder_c_3=tim;
433 	}
434 
435 /* now process blackout regions */
436 v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
437 num_blackout_regions = v;
438 
439 if(num_blackout_regions)
440 	{
441 	for(i=0;i<num_blackout_regions;i++)
442 		{
443 		struct blackout_region_t *bt = calloc_2(1, sizeof(struct blackout_region_t));
444 		TimeType tim;
445 
446 		if(!bt_head)
447 			{
448 			bt_head = bt_curr = bt;
449 			}
450 			else
451 			{
452 			bt_curr->next = bt;
453 			bt_curr = bt;
454 			}
455 
456 		v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
457 		tim = v;
458 		bt->bstart = tim;
459 
460 		v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
461 		tim = v;
462 		bt->bend = tim;
463 		}
464 
465 	GLOBALS->blackout_regions = bt_head;
466 	}
467 
468 vlist_packer_decompress_destroy((char *)depacked);
469 
470 return(rc);
471 }
472 
473 #ifdef HAVE_SYS_STAT_H
read_fastload_header(struct stat * st)474 static int read_fastload_header(struct stat *st)
475 #else
476 static int read_fastload_header(void)
477 #endif
478 {
479 int rc = 0;
480 int fs_rc = fseeko(GLOBALS->vlist_handle, 0, SEEK_END);
481 off_t ftlen = ftello(GLOBALS->vlist_handle);
482 guint64 v = 0;
483 int ch;
484 int shamt = 0;
485 unsigned char *depacked = NULL;
486 struct vlist_t *vl;
487 unsigned int list_size;
488 unsigned char *pnt;
489 #ifdef HAVE_SYS_STAT_H
490 struct stat mystat;
491 int stat_rc = stat(GLOBALS->loaded_file_name, &mystat);
492 #endif
493 
494 if((fs_rc<0)||(!ftlen))
495 	{
496 	goto bail;
497 	}
498 
499 do	{
500 	ftlen--;
501 	fseeko(GLOBALS->vlist_handle, ftlen, SEEK_SET);
502 	ch = fgetc(GLOBALS->vlist_handle);
503 	if(ch == EOF) { errno = 0; goto bail; }
504 	v |= ((guint64)(ch & 0x7f)) << shamt;
505 	shamt += 7;
506 	} while(!(ch & 0x80));
507 
508 vl = (struct vlist_t *)(intptr_t)v;
509 vlist_uncompress(&vl);
510 depacked = vlist_packer_decompress(vl, &list_size);
511 vlist_destroy(vl);
512 
513 pnt = depacked;
514 v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
515 
516 #ifdef HAVE_SYS_STAT_H
517 if((stat_rc)||(v != (guint64)mystat.st_size))
518 	{
519 	goto bail;
520 	}
521 #endif
522 
523 v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80));
524 
525 #ifdef HAVE_SYS_STAT_H
526 if(v != (guint64)st->st_mtime)
527 	{
528 	goto bail;
529 	}
530 #endif
531 
532 rc = 1;
533 GLOBALS->fastload_depacked = (char *)depacked;
534 GLOBALS->fastload_current = (char *)pnt;
535 
536 bail:
537 if(!rc) vlist_packer_decompress_destroy((char *)depacked);
538 return(rc);
539 }
540 
541 /**/
542 
543 #undef VCD_BSEARCH_IS_PERFECT		/* bsearch is imperfect under linux, but OK under AIX */
544 
545 static void add_histent(TimeType time, struct Node *n, char ch, int regadd, char *vector);
546 static void vcd_build_symbols(void);
547 static void vcd_cleanup(void);
548 static void evcd_strcpy(char *dst, char *src);
549 
550 /******************************************************************/
551 
552 enum Tokens   { T_VAR, T_END, T_SCOPE, T_UPSCOPE,
553 		T_COMMENT, T_DATE, T_DUMPALL, T_DUMPOFF, T_DUMPON,
554 		T_DUMPVARS, T_ENDDEFINITIONS,
555 		T_DUMPPORTS, T_DUMPPORTSOFF, T_DUMPPORTSON, T_DUMPPORTSALL,
556 		T_TIMESCALE, T_VERSION, T_VCDCLOSE, T_TIMEZERO,
557 		T_EOF, T_STRING, T_UNKNOWN_KEY };
558 
559 static char *tokens[]={ "var", "end", "scope", "upscope",
560                  "comment", "date", "dumpall", "dumpoff", "dumpon",
561                  "dumpvars", "enddefinitions",
562                  "dumpports", "dumpportsoff", "dumpportson", "dumpportsall",
563                  "timescale", "version", "vcdclose", "timezero",
564                  "", "", "" };
565 
566 #define NUM_TOKENS 19
567 
568 
569 #define T_GET tok=get_token();if((tok==T_END)||(tok==T_EOF))break;
570 
571 /******************************************************************/
572 
vcdid_hash(char * s,int len)573 static unsigned int vcdid_hash(char *s, int len)
574 {
575 unsigned int val=0;
576 int i;
577 
578 s+=(len-1);
579 
580 for(i=0;i<len;i++)
581         {
582         val *= 94;
583         val += (((unsigned char)*s) - 32);
584         s--;
585         }
586 
587 return(val);
588 }
589 
590 /******************************************************************/
591 
592 /*
593  * bsearch compare
594  */
vcdsymbsearchcompare(const void * s1,const void * s2)595 static int vcdsymbsearchcompare(const void *s1, const void *s2)
596 {
597 char *v1;
598 struct vcdsymbol *v2;
599 
600 v1=(char *)s1;
601 v2=*((struct vcdsymbol **)s2);
602 
603 return(strcmp(v1, v2->id));
604 }
605 
606 
607 /*
608  * actual bsearch
609  */
bsearch_vcd(char * key,int len)610 static struct vcdsymbol *bsearch_vcd(char *key, int len)
611 {
612 struct vcdsymbol **v;
613 struct vcdsymbol *t;
614 
615 if(GLOBALS->indexed_vcd_recoder_c_3)
616         {
617         unsigned int hsh = vcdid_hash(key, len);
618         if((hsh>=GLOBALS->vcd_minid_vcd_recoder_c_3)&&(hsh<=GLOBALS->vcd_maxid_vcd_recoder_c_3))
619                 {
620                 return(GLOBALS->indexed_vcd_recoder_c_3[hsh-GLOBALS->vcd_minid_vcd_recoder_c_3]);
621                 }
622 
623 	return(NULL);
624         }
625 
626 if(GLOBALS->sorted_vcd_recoder_c_3)
627 	{
628 	v=(struct vcdsymbol **)bsearch(key, GLOBALS->sorted_vcd_recoder_c_3, GLOBALS->numsyms_vcd_recoder_c_3,
629 		sizeof(struct vcdsymbol *), vcdsymbsearchcompare);
630 
631 	if(v)
632 		{
633 		#ifndef VCD_BSEARCH_IS_PERFECT
634 			for(;;)
635 				{
636 				t=*v;
637 
638 				if((v==GLOBALS->sorted_vcd_recoder_c_3)||(strcmp((*(--v))->id, key)))
639 					{
640 					return(t);
641 					}
642 				}
643 		#else
644 			return(*v);
645 		#endif
646 		}
647 		else
648 		{
649 		return(NULL);
650 		}
651 	}
652 	else
653 	{
654 	if(!GLOBALS->err_vcd_recoder_c_3)
655 		{
656 		fprintf(stderr, "Near byte %d, VCD search table NULL..is this a VCD file?\n", (int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3)));
657 		GLOBALS->err_vcd_recoder_c_3=1;
658 		}
659 	return(NULL);
660 	}
661 }
662 
663 
664 /*
665  * sort on vcdsymbol pointers
666  */
vcdsymcompare(const void * s1,const void * s2)667 static int vcdsymcompare(const void *s1, const void *s2)
668 {
669 struct vcdsymbol *v1, *v2;
670 
671 v1=*((struct vcdsymbol **)s1);
672 v2=*((struct vcdsymbol **)s2);
673 
674 return(strcmp(v1->id, v2->id));
675 }
676 
677 
678 /*
679  * create sorted (by id) table
680  */
create_sorted_table(void)681 static void create_sorted_table(void)
682 {
683 struct vcdsymbol *v;
684 struct vcdsymbol **pnt;
685 unsigned int vcd_distance;
686 
687 if(GLOBALS->sorted_vcd_recoder_c_3)
688 	{
689 	free_2(GLOBALS->sorted_vcd_recoder_c_3);	/* this means we saw a 2nd enddefinition chunk! */
690 	GLOBALS->sorted_vcd_recoder_c_3=NULL;
691 	}
692 
693 if(GLOBALS->indexed_vcd_recoder_c_3)
694 	{
695 	free_2(GLOBALS->indexed_vcd_recoder_c_3);
696 	GLOBALS->indexed_vcd_recoder_c_3=NULL;
697 	}
698 
699 if(GLOBALS->numsyms_vcd_recoder_c_3)
700 	{
701         vcd_distance = GLOBALS->vcd_maxid_vcd_recoder_c_3 - GLOBALS->vcd_minid_vcd_recoder_c_3 + 1;
702 
703         if((vcd_distance <= VCD_INDEXSIZ)||(!GLOBALS->vcd_hash_kill))
704                 {
705                 GLOBALS->indexed_vcd_recoder_c_3 = (struct vcdsymbol **)calloc_2(vcd_distance, sizeof(struct vcdsymbol *));
706 
707 		/* printf("%d symbols span ID range of %d, using indexing... hash_kill = %d\n", GLOBALS->numsyms_vcd_recoder_c_3, vcd_distance, GLOBALS->vcd_hash_kill);  */
708 
709                 v=GLOBALS->vcdsymroot_vcd_recoder_c_3;
710                 while(v)
711                         {
712                         if(!GLOBALS->indexed_vcd_recoder_c_3[v->nid - GLOBALS->vcd_minid_vcd_recoder_c_3]) GLOBALS->indexed_vcd_recoder_c_3[v->nid - GLOBALS->vcd_minid_vcd_recoder_c_3] = v;
713                         v=v->next;
714                         }
715                 }
716                 else
717 		{
718 		pnt=GLOBALS->sorted_vcd_recoder_c_3=(struct vcdsymbol **)calloc_2(GLOBALS->numsyms_vcd_recoder_c_3, sizeof(struct vcdsymbol *));
719 		v=GLOBALS->vcdsymroot_vcd_recoder_c_3;
720 		while(v)
721 			{
722 			*(pnt++)=v;
723 			v=v->next;
724 			}
725 
726 		qsort(GLOBALS->sorted_vcd_recoder_c_3, GLOBALS->numsyms_vcd_recoder_c_3, sizeof(struct vcdsymbol *), vcdsymcompare);
727 		}
728 	}
729 }
730 
731 /******************************************************************/
732 
vlist_emit_finalize(void)733 static unsigned int vlist_emit_finalize(void)
734 {
735 struct vcdsymbol *v /* , *vprime */; /* scan-build */
736 struct vlist_t *vlist;
737 char vlist_prepack = GLOBALS->vlist_prepack;
738 int cnt = 0;
739 
740 v=GLOBALS->vcdsymroot_vcd_recoder_c_3;
741 while(v)
742 	{
743 	nptr n = v->narray[0];
744 
745 	set_vcd_vartype(v, n);
746 
747 	if(n->mv.mvlfac_vlist)
748 		{
749 		if(vlist_prepack)
750 			{
751 	                vlist_packer_finalize(n->mv.mvlfac_packer_vlist);
752 	                vlist = n->mv.mvlfac_packer_vlist->v;
753 	                free_2(n->mv.mvlfac_packer_vlist);
754 	                n->mv.mvlfac_vlist = vlist;
755 	                vlist_freeze(&n->mv.mvlfac_vlist);
756 			}
757 			else
758 			{
759 			vlist_freeze(&n->mv.mvlfac_vlist);
760 			}
761 		}
762 		else
763 		{
764 		n->mv.mvlfac_vlist = vlist_prepack ? ((struct vlist_t *)vlist_packer_create()) : vlist_create(sizeof(char));
765 
766 		if((/* vprime= */ bsearch_vcd(v->id, strlen(v->id)))==v) /* hash mish means dup net */ /* scan-build */
767 			{
768 			switch(v->vartype)
769 				{
770 				case V_REAL:
771 		                          	vlist_emit_uv32(&n->mv.mvlfac_vlist, 'R');
772 		                                vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->vartype);
773 		                                vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->size);
774 						vlist_emit_uv32(&n->mv.mvlfac_vlist, 0);
775 						vlist_emit_string(&n->mv.mvlfac_vlist, "NaN");
776 						break;
777 
778 				case V_STRINGTYPE:
779 						vlist_emit_uv32(&n->mv.mvlfac_vlist, 'S');
780 		                                vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->vartype);
781 		                                vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->size);
782 						vlist_emit_uv32(&n->mv.mvlfac_vlist, 0);
783 						vlist_emit_string(&n->mv.mvlfac_vlist, "UNDEF");
784 						break;
785 
786 				default:
787 					if(v->size==1)
788 						{
789 	                                        vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)'0');
790 	                                        vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->vartype);
791 						vlist_emit_uv32(&n->mv.mvlfac_vlist, RCV_X);
792 						}
793 						else
794 						{
795 		                                vlist_emit_uv32(&n->mv.mvlfac_vlist, 'B');
796 		                                vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->vartype);
797 		                                vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->size);
798 						vlist_emit_uv32(&n->mv.mvlfac_vlist, 0);
799 						vlist_emit_mvl9_string(&n->mv.mvlfac_vlist, "x");
800 						}
801 					break;
802 				}
803 			}
804 
805 		if(vlist_prepack)
806 			{
807 	                vlist_packer_finalize(n->mv.mvlfac_packer_vlist);
808 	                vlist = n->mv.mvlfac_packer_vlist->v;
809 	                free_2(n->mv.mvlfac_packer_vlist);
810 	                n->mv.mvlfac_vlist = vlist;
811 	                vlist_freeze(&n->mv.mvlfac_vlist);
812 			}
813 			else
814 			{
815 			vlist_freeze(&n->mv.mvlfac_vlist);
816 			}
817 		}
818 	v=v->next;
819 	cnt++;
820 	}
821 
822 return(cnt);
823 }
824 
825 /******************************************************************/
826 
827 /*
828  * single char get inlined/optimized
829  */
getch_alloc(void)830 static void getch_alloc(void)
831 {
832 GLOBALS->vend_vcd_recoder_c_3=GLOBALS->vst_vcd_recoder_c_3=GLOBALS->vcdbuf_vcd_recoder_c_3=(char *)calloc_2(1,VCD_BSIZ);
833 }
834 
getch_free(void)835 static void getch_free(void)
836 {
837 free_2(GLOBALS->vcdbuf_vcd_recoder_c_3);
838 GLOBALS->vcdbuf_vcd_recoder_c_3=GLOBALS->vst_vcd_recoder_c_3=GLOBALS->vend_vcd_recoder_c_3=NULL;
839 }
840 
841 
842 
getch_fetch(void)843 static int getch_fetch(void)
844 {
845 size_t rd;
846 
847 errno = 0;
848 if(feof(GLOBALS->vcd_handle_vcd_recoder_c_2)) return(-1);
849 
850 GLOBALS->vcdbyteno_vcd_recoder_c_3+=(GLOBALS->vend_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3);
851 rd=fread(GLOBALS->vcdbuf_vcd_recoder_c_3, sizeof(char), VCD_BSIZ, GLOBALS->vcd_handle_vcd_recoder_c_2);
852 GLOBALS->vend_vcd_recoder_c_3=(GLOBALS->vst_vcd_recoder_c_3=GLOBALS->vcdbuf_vcd_recoder_c_3)+rd;
853 
854 if((!rd)||(errno)) return(-1);
855 
856 if(GLOBALS->vcd_fsiz_vcd_recoder_c_2)
857 	{
858 	splash_sync(GLOBALS->vcdbyteno_vcd_recoder_c_3, GLOBALS->vcd_fsiz_vcd_recoder_c_2); /* gnome 2.18 seems to set errno so splash moved here... */
859 	}
860 
861 return((int)(*GLOBALS->vst_vcd_recoder_c_3));
862 }
863 
getch(void)864 static inline signed char getch(void) {
865   signed char ch = (GLOBALS->vst_vcd_recoder_c_3!=GLOBALS->vend_vcd_recoder_c_3)?((int)(*GLOBALS->vst_vcd_recoder_c_3)):(getch_fetch());
866   GLOBALS->vst_vcd_recoder_c_3++;
867   return(ch);
868 }
869 
getch_peek(void)870 static inline signed char getch_peek(void) {
871   signed char ch = (GLOBALS->vst_vcd_recoder_c_3!=GLOBALS->vend_vcd_recoder_c_3)?((int)(*GLOBALS->vst_vcd_recoder_c_3)):(getch_fetch());
872   /* no increment */
873   return(ch);
874 }
875 
getch_patched(void)876 static int getch_patched(void)
877 {
878 char ch;
879 
880 ch=*GLOBALS->vsplitcurr_vcd_recoder_c_3;
881 if(!ch)
882 	{
883 	return(-1);
884 	}
885 	else
886 	{
887 	GLOBALS->vsplitcurr_vcd_recoder_c_3++;
888 	return((int)ch);
889 	}
890 }
891 
892 /*
893  * simple tokenizer
894  */
get_token(void)895 static int get_token(void)
896 {
897 int ch;
898 int i, len=0;
899 int is_string=0;
900 char *yyshadow;
901 
902 for(;;)
903 	{
904 	ch=getch();
905 	if(ch<0) return(T_EOF);
906 	if(ch<=' ') continue;	/* val<=' ' is a quick whitespace check      */
907 	break;			/* (take advantage of fact that vcd is text) */
908 	}
909 if(ch=='$')
910 	{
911 	GLOBALS->yytext_vcd_recoder_c_3[len++]=ch;
912 	for(;;)
913 		{
914 		ch=getch();
915 		if(ch<0) return(T_EOF);
916 		if(ch<=' ') continue;
917 		break;
918 		}
919 	}
920 	else
921 	{
922 	is_string=1;
923 	}
924 
925 for(GLOBALS->yytext_vcd_recoder_c_3[len++]=ch;;GLOBALS->yytext_vcd_recoder_c_3[len++]=ch)
926 	{
927 	if(len==GLOBALS->T_MAX_STR_vcd_recoder_c_3)
928 		{
929 		GLOBALS->yytext_vcd_recoder_c_3=(char *)realloc_2(GLOBALS->yytext_vcd_recoder_c_3, (GLOBALS->T_MAX_STR_vcd_recoder_c_3=GLOBALS->T_MAX_STR_vcd_recoder_c_3*2)+1);
930 		}
931 	ch=getch();
932 	if(ch<=' ') break;
933 	}
934 GLOBALS->yytext_vcd_recoder_c_3[len]=0;	/* terminator */
935 
936 if(is_string)
937 	{
938 	GLOBALS->yylen_vcd_recoder_c_3=len;
939 	return(T_STRING);
940 	}
941 
942 yyshadow=GLOBALS->yytext_vcd_recoder_c_3;
943 do
944 {
945 yyshadow++;
946 for(i=0;i<NUM_TOKENS;i++)
947 	{
948 	if(!strcmp(yyshadow,tokens[i]))
949 		{
950 		return(i);
951 		}
952 	}
953 
954 } while(*yyshadow=='$'); /* fix for RCS ids in version strings */
955 
956 return(T_UNKNOWN_KEY);
957 }
958 
959 
get_vartoken_patched(int match_kw)960 static int get_vartoken_patched(int match_kw)
961 {
962 int ch;
963 int len=0;
964 
965 if(!GLOBALS->var_prevch_vcd_recoder_c_3)
966 	{
967 	for(;;)
968 		{
969 		ch=getch_patched();
970 		if(ch<0) { free_2(GLOBALS->varsplit_vcd_recoder_c_3); GLOBALS->varsplit_vcd_recoder_c_3=NULL; return(V_END); }
971 		if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue;
972 		break;
973 		}
974 	}
975 	else
976 	{
977 	ch=GLOBALS->var_prevch_vcd_recoder_c_3;
978 	GLOBALS->var_prevch_vcd_recoder_c_3=0;
979 	}
980 
981 if(ch=='[') return(V_LB);
982 if(ch==':') return(V_COLON);
983 if(ch==']') return(V_RB);
984 
985 for(GLOBALS->yytext_vcd_recoder_c_3[len++]=ch;;GLOBALS->yytext_vcd_recoder_c_3[len++]=ch)
986 	{
987 	if(len==GLOBALS->T_MAX_STR_vcd_recoder_c_3)
988 		{
989 		GLOBALS->yytext_vcd_recoder_c_3=(char *)realloc_2(GLOBALS->yytext_vcd_recoder_c_3, (GLOBALS->T_MAX_STR_vcd_recoder_c_3=GLOBALS->T_MAX_STR_vcd_recoder_c_3*2)+1);
990 		}
991 	ch=getch_patched();
992 	if(ch<0) { free_2(GLOBALS->varsplit_vcd_recoder_c_3); GLOBALS->varsplit_vcd_recoder_c_3=NULL; break; }
993 	if((ch==':')||(ch==']'))
994 		{
995 		GLOBALS->var_prevch_vcd_recoder_c_3=ch;
996 		break;
997 		}
998 	}
999 GLOBALS->yytext_vcd_recoder_c_3[len]=0;	/* terminator */
1000 
1001 if(match_kw)
1002 	{
1003 	int vr = vcd_keyword_code(GLOBALS->yytext_vcd_recoder_c_3, len);
1004 	if(vr != V_STRING)
1005 		{
1006 		if(ch<0) { free_2(GLOBALS->varsplit_vcd_recoder_c_3); GLOBALS->varsplit_vcd_recoder_c_3=NULL; }
1007 		return(vr);
1008 		}
1009 	}
1010 
1011 GLOBALS->yylen_vcd_recoder_c_3=len;
1012 if(ch<0) { free_2(GLOBALS->varsplit_vcd_recoder_c_3); GLOBALS->varsplit_vcd_recoder_c_3=NULL; }
1013 return(V_STRING);
1014 }
1015 
get_vartoken(int match_kw)1016 static int get_vartoken(int match_kw)
1017 {
1018 int ch;
1019 int len=0;
1020 
1021 if(GLOBALS->varsplit_vcd_recoder_c_3)
1022 	{
1023 	int rc=get_vartoken_patched(match_kw);
1024 	if(rc!=V_END) return(rc);
1025 	GLOBALS->var_prevch_vcd_recoder_c_3=0;
1026 	}
1027 
1028 if(!GLOBALS->var_prevch_vcd_recoder_c_3)
1029 	{
1030 	for(;;)
1031 		{
1032 		ch=getch();
1033 		if(ch<0) return(V_END);
1034 		if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue;
1035 		break;
1036 		}
1037 	}
1038 	else
1039 	{
1040 	ch=GLOBALS->var_prevch_vcd_recoder_c_3;
1041 	GLOBALS->var_prevch_vcd_recoder_c_3=0;
1042 	}
1043 
1044 if(ch=='[') return(V_LB);
1045 if(ch==':') return(V_COLON);
1046 if(ch==']') return(V_RB);
1047 
1048 if(ch=='#')	/* for MTI System Verilog '$var reg 64 >w #implicit-var###VarElem:ram_di[0.0] [63:0] $end' style declarations */
1049 	{	/* debussy simply escapes until the space */
1050 	GLOBALS->yytext_vcd_recoder_c_3[len++]= '\\';
1051 	}
1052 
1053 for(GLOBALS->yytext_vcd_recoder_c_3[len++]=ch;;GLOBALS->yytext_vcd_recoder_c_3[len++]=ch)
1054 	{
1055 	if(len==GLOBALS->T_MAX_STR_vcd_recoder_c_3)
1056 		{
1057 		GLOBALS->yytext_vcd_recoder_c_3=(char *)realloc_2(GLOBALS->yytext_vcd_recoder_c_3, (GLOBALS->T_MAX_STR_vcd_recoder_c_3=GLOBALS->T_MAX_STR_vcd_recoder_c_3*2)+1);
1058 		}
1059 
1060 	ch=getch();
1061 	if(ch==' ')
1062 		{
1063 		if(match_kw) break;
1064 		if(getch_peek() == '[')
1065 			{
1066 			ch = getch();
1067 			GLOBALS->varsplit_vcd_recoder_c_3=GLOBALS->yytext_vcd_recoder_c_3+len;	/* keep looping so we get the *last* one */
1068 			continue;
1069 			}
1070 		}
1071 
1072 	if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break;
1073 	if((ch=='[')&&(GLOBALS->yytext_vcd_recoder_c_3[0]!='\\'))
1074 		{
1075 		GLOBALS->varsplit_vcd_recoder_c_3=GLOBALS->yytext_vcd_recoder_c_3+len;		/* keep looping so we get the *last* one */
1076 		}
1077 	else
1078 	if(((ch==':')||(ch==']'))&&(!GLOBALS->varsplit_vcd_recoder_c_3)&&(GLOBALS->yytext_vcd_recoder_c_3[0]!='\\'))
1079 		{
1080 		GLOBALS->var_prevch_vcd_recoder_c_3=ch;
1081 		break;
1082 		}
1083 	}
1084 
1085 GLOBALS->yytext_vcd_recoder_c_3[len]=0;	/* absolute terminator */
1086 if((GLOBALS->varsplit_vcd_recoder_c_3)&&(GLOBALS->yytext_vcd_recoder_c_3[len-1]==']'))
1087 	{
1088 	char *vst;
1089 	vst=malloc_2(strlen(GLOBALS->varsplit_vcd_recoder_c_3)+1);
1090 	strcpy(vst, GLOBALS->varsplit_vcd_recoder_c_3);
1091 
1092 	*GLOBALS->varsplit_vcd_recoder_c_3=0x00;		/* zero out var name at the left bracket */
1093 	len=GLOBALS->varsplit_vcd_recoder_c_3-GLOBALS->yytext_vcd_recoder_c_3;
1094 
1095 	GLOBALS->varsplit_vcd_recoder_c_3=GLOBALS->vsplitcurr_vcd_recoder_c_3=vst;
1096 	GLOBALS->var_prevch_vcd_recoder_c_3=0;
1097 	}
1098 	else
1099 	{
1100 	GLOBALS->varsplit_vcd_recoder_c_3=NULL;
1101 	}
1102 
1103 if(match_kw)
1104 	{
1105         int vr = vcd_keyword_code(GLOBALS->yytext_vcd_recoder_c_3, len);
1106         if(vr != V_STRING)
1107 		{
1108 		return(vr);
1109 		}
1110 	}
1111 
1112 GLOBALS->yylen_vcd_recoder_c_3=len;
1113 return(V_STRING);
1114 }
1115 
get_strtoken(void)1116 static int get_strtoken(void)
1117 {
1118 int ch;
1119 int len=0;
1120 
1121 if(!GLOBALS->var_prevch_vcd_recoder_c_3)
1122       {
1123       for(;;)
1124               {
1125               ch=getch();
1126               if(ch<0) return(V_END);
1127               if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue;
1128               break;
1129               }
1130       }
1131       else
1132       {
1133       ch=GLOBALS->var_prevch_vcd_recoder_c_3;
1134       GLOBALS->var_prevch_vcd_recoder_c_3=0;
1135       }
1136 
1137 for(GLOBALS->yytext_vcd_recoder_c_3[len++]=ch;;GLOBALS->yytext_vcd_recoder_c_3[len++]=ch)
1138       {
1139 	if(len==GLOBALS->T_MAX_STR_vcd_recoder_c_3)
1140 		{
1141 		GLOBALS->yytext_vcd_recoder_c_3=(char *)realloc_2(GLOBALS->yytext_vcd_recoder_c_3, (GLOBALS->T_MAX_STR_vcd_recoder_c_3=GLOBALS->T_MAX_STR_vcd_recoder_c_3*2)+1);
1142 		}
1143       ch=getch();
1144       if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break;
1145       }
1146 GLOBALS->yytext_vcd_recoder_c_3[len]=0;        /* terminator */
1147 
1148 GLOBALS->yylen_vcd_recoder_c_3=len;
1149 return(V_STRING);
1150 }
1151 
sync_end(char * hdr)1152 static void sync_end(char *hdr)
1153 {
1154 int tok;
1155 
1156 if(hdr) { DEBUG(fprintf(stderr,"%s",hdr)); }
1157 for(;;)
1158 	{
1159 	tok=get_token();
1160 	if((tok==T_END)||(tok==T_EOF)) break;
1161 	if(hdr) { DEBUG(fprintf(stderr," %s",GLOBALS->yytext_vcd_recoder_c_3)); }
1162 	}
1163 if(hdr) { DEBUG(fprintf(stderr,"\n")); }
1164 }
1165 
version_sync_end(char * hdr)1166 static int version_sync_end(char *hdr)
1167 {
1168 int tok;
1169 int rc = 0;
1170 
1171 if(hdr) { DEBUG(fprintf(stderr,"%s",hdr)); }
1172 for(;;)
1173 	{
1174 	tok=get_token();
1175 	if((tok==T_END)||(tok==T_EOF)) break;
1176 	if(hdr) { DEBUG(fprintf(stderr," %s",GLOBALS->yytext_vcd_recoder_c_3)); }
1177 	if(strstr(GLOBALS->yytext_vcd_recoder_c_3, "Icarus"))	/* turn off autocoalesce for Icarus */
1178 		{
1179 		GLOBALS->autocoalesce = 0;
1180 		rc = 1;
1181 		}
1182 	}
1183 if(hdr) { DEBUG(fprintf(stderr,"\n")); }
1184 return(rc);
1185 }
1186 
parse_valuechange(void)1187 static void parse_valuechange(void)
1188 {
1189 struct vcdsymbol *v;
1190 char *vector;
1191 int vlen;
1192 unsigned char typ;
1193 
1194 switch((typ = GLOBALS->yytext_vcd_recoder_c_3[0]))
1195 	{
1196 	/* encode bits as (time delta<<4) + (enum AnalyzerBits value) */
1197         case '0':
1198         case '1':
1199         case 'x': case 'X':
1200         case 'z': case 'Z':
1201         case 'h': case 'H':
1202         case 'u': case 'U':
1203         case 'w': case 'W':
1204         case 'l': case 'L':
1205         case '-':
1206                 if(GLOBALS->yylen_vcd_recoder_c_3>1)
1207                         {
1208                         v=bsearch_vcd(GLOBALS->yytext_vcd_recoder_c_3+1, GLOBALS->yylen_vcd_recoder_c_3-1);
1209                         if(!v)
1210                                 {
1211                                 fprintf(stderr,"Near byte %d, Unknown VCD identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3)),GLOBALS->yytext_vcd_recoder_c_3+1);
1212 				malform_eof_fix();
1213                                 }
1214                                 else
1215                                 {
1216 				nptr n = v->narray[0];
1217 				unsigned int time_delta;
1218 				unsigned int rcv;
1219 
1220 				if(!n->mv.mvlfac_vlist) /* overloaded for vlist, numhist = last position used */
1221 					{
1222 					n->mv.mvlfac_vlist = (GLOBALS->vlist_prepack) ? ((struct vlist_t *)vlist_packer_create()) : vlist_create(sizeof(char));
1223 					vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)'0'); /* represents single bit routine for decompression */
1224 					vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->vartype);
1225 					}
1226 
1227 				time_delta = GLOBALS->time_vlist_count_vcd_recoder_c_1 - (unsigned int)n->numhist;
1228 				n->numhist = GLOBALS->time_vlist_count_vcd_recoder_c_1;
1229 
1230 				switch(GLOBALS->yytext_vcd_recoder_c_3[0])
1231 				        {
1232 				        case '0':
1233 				        case '1':		rcv = ((GLOBALS->yytext_vcd_recoder_c_3[0]&1)<<1) | (time_delta<<2);
1234 								break; /* pack more delta bits in for 0/1 vchs */
1235 
1236 				        case 'x': case 'X':	rcv = RCV_X | (time_delta<<4); break;
1237 				        case 'z': case 'Z':	rcv = RCV_Z | (time_delta<<4); break;
1238 				        case 'h': case 'H':	rcv = RCV_H | (time_delta<<4); break;
1239 				        case 'u': case 'U':	rcv = RCV_U | (time_delta<<4); break;
1240 				        case 'w': case 'W':     rcv = RCV_W | (time_delta<<4); break;
1241 				        case 'l': case 'L':	rcv = RCV_L | (time_delta<<4); break;
1242 					default:		rcv = RCV_D | (time_delta<<4); break;
1243 					}
1244 
1245 				vlist_emit_uv32(&n->mv.mvlfac_vlist, rcv);
1246                                 }
1247                         }
1248                         else
1249                         {
1250                         fprintf(stderr,"Near byte %d, Malformed VCD identifier\n", (int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3)));
1251 			malform_eof_fix();
1252                         }
1253                 break;
1254 
1255 	/* encode everything else literally as a time delta + a string */
1256 #ifndef STRICT_VCD_ONLY
1257         case 's':
1258         case 'S':
1259                 vector=wave_alloca(GLOBALS->yylen_cache_vcd_recoder_c_3=GLOBALS->yylen_vcd_recoder_c_3);
1260 		vlen = fstUtilityEscToBin((unsigned char *)vector, (unsigned char *)(GLOBALS->yytext_vcd_recoder_c_3+1), GLOBALS->yylen_vcd_recoder_c_3-1);
1261 		vector[vlen] = 0;
1262 
1263                 get_strtoken();
1264 		goto process_binary;
1265 #endif
1266         case 'b':
1267         case 'B':
1268         case 'r':
1269         case 'R':
1270                 vector=wave_alloca(GLOBALS->yylen_cache_vcd_recoder_c_3=GLOBALS->yylen_vcd_recoder_c_3);
1271                 strcpy(vector,GLOBALS->yytext_vcd_recoder_c_3+1);
1272                 vlen=GLOBALS->yylen_vcd_recoder_c_3-1;
1273 
1274                 get_strtoken();
1275 process_binary:
1276                 v=bsearch_vcd(GLOBALS->yytext_vcd_recoder_c_3, GLOBALS->yylen_vcd_recoder_c_3);
1277                 if(!v)
1278 			{
1279                         fprintf(stderr,"Near byte %d, Unknown VCD identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3)),GLOBALS->yytext_vcd_recoder_c_3+1);
1280 			malform_eof_fix();
1281                         }
1282                         else
1283                         {
1284 			nptr n = v->narray[0];
1285 			unsigned int time_delta;
1286 
1287 			if(!n->mv.mvlfac_vlist) /* overloaded for vlist, numhist = last position used */
1288 				{
1289 				unsigned char typ2 = toupper(typ);
1290 				n->mv.mvlfac_vlist = (GLOBALS->vlist_prepack) ? ((struct vlist_t *)vlist_packer_create()) : vlist_create(sizeof(char));
1291 
1292 				if((v->vartype!=V_REAL) && (v->vartype!=V_STRINGTYPE))
1293 					{
1294                                         if((typ2=='R')||(typ2=='S'))
1295                                                 {
1296                                                 typ2 = 'B';     /* ok, typical case...fix as 'r' on bits variable causes recoder crash during trace extraction */
1297                                                 }
1298 					}
1299 					else
1300 					{
1301 					if(typ2=='B')
1302 						{
1303 						typ2 = 'S';	/* should never be necessary...this is defensive */
1304 						}
1305 					}
1306 
1307 
1308 				vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)toupper(typ2)); /* B/R/P/S for decompress */
1309 				vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->vartype);
1310 				vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->size);
1311 				}
1312 
1313 			time_delta = GLOBALS->time_vlist_count_vcd_recoder_c_1 - (unsigned int)n->numhist;
1314 			n->numhist = GLOBALS->time_vlist_count_vcd_recoder_c_1;
1315 
1316 			vlist_emit_uv32(&n->mv.mvlfac_vlist, time_delta);
1317 
1318 			if((typ=='b')||(typ=='B'))
1319 				{
1320 				if((v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE))
1321 					{
1322 					vlist_emit_mvl9_string(&n->mv.mvlfac_vlist, vector);
1323 					}
1324 					else
1325 					{
1326 					vlist_emit_string(&n->mv.mvlfac_vlist, vector);
1327 					}
1328 				}
1329 				else
1330 				{
1331 				if((v->vartype == V_REAL)||(v->vartype == V_STRINGTYPE)||(typ=='s')||(typ=='S'))
1332 					{
1333 					vlist_emit_string(&n->mv.mvlfac_vlist, vector);
1334 					}
1335 					else
1336 					{
1337 					char *bits = wave_alloca(v->size + 1);
1338 					int i, j, k=0;
1339 
1340 					memset(bits, 0x0, v->size + 1);
1341 
1342 					for(i=0;i<vlen;i++)
1343 						{
1344 						for(j=0;j<8;j++)
1345 							{
1346 							bits[k++] = ((vector[i] >> (7-j)) & 1) | '0';
1347 							if(k >= v->size) goto bit_term;
1348 							}
1349 						}
1350 
1351 					bit_term:
1352 					vlist_emit_mvl9_string(&n->mv.mvlfac_vlist, bits);
1353 					}
1354 				}
1355                         }
1356 		break;
1357 
1358 	case 'p':
1359 	case 'P':
1360 		/* extract port dump value.. */
1361 		vector=wave_alloca(GLOBALS->yylen_cache_vcd_recoder_c_3=GLOBALS->yylen_vcd_recoder_c_3);
1362 		evcd_strcpy(vector,GLOBALS->yytext_vcd_recoder_c_3+1);	/* convert to regular vcd */
1363 		vlen=GLOBALS->yylen_vcd_recoder_c_3-1;
1364 
1365 		get_strtoken();	/* throw away 0_strength_component */
1366 		get_strtoken(); /* throw away 0_strength_component */
1367 		get_strtoken(); /* this is the id                  */
1368 
1369 		typ = 'b';			/* convert to regular vcd */
1370 		goto process_binary; /* store string literally */
1371 
1372 	default:
1373 		break;
1374 	}
1375 }
1376 
1377 
evcd_strcpy(char * dst,char * src)1378 static void evcd_strcpy(char *dst, char *src)
1379 {
1380 static const char *evcd="DUNZduLHXTlh01?FAaBbCcf";
1381 static const char  *vcd="01xz0101xz0101xzxxxxxxz";
1382 
1383 char ch;
1384 int i;
1385 
1386 while((ch=*src))
1387 	{
1388 	for(i=0;i<23;i++)
1389 		{
1390 		if(evcd[i]==ch)
1391 			{
1392 			*dst=vcd[i];
1393 			break;
1394 			}
1395 		}
1396 	if(i==23) *dst='x';
1397 
1398 	src++;
1399 	dst++;
1400 	}
1401 
1402 *dst=0;	/* null terminate destination */
1403 }
1404 
1405 
vcd_parse(void)1406 static void vcd_parse(void)
1407 {
1408 int tok;
1409 unsigned char ttype;
1410 int disable_autocoalesce = 0;
1411 
1412 for(;;)
1413 	{
1414 	switch(get_token())
1415 		{
1416 		case T_COMMENT:
1417 			sync_end("COMMENT:");
1418 			break;
1419 		case T_DATE:
1420 			sync_end("DATE:");
1421 			break;
1422 		case T_VERSION:
1423 			disable_autocoalesce = version_sync_end("VERSION:");
1424 			break;
1425 		case T_TIMEZERO:
1426 			{
1427 			int vtok=get_token();
1428 			if((vtok==T_END)||(vtok==T_EOF)) break;
1429 			GLOBALS->global_time_offset=atoi_64(GLOBALS->yytext_vcd_recoder_c_3);
1430 
1431 			DEBUG(fprintf(stderr,"TIMEZERO: "TTFormat"\n",GLOBALS->global_time_offset));
1432 			sync_end(NULL);
1433 			}
1434 			break;
1435 		case T_TIMESCALE:
1436 			{
1437 			int vtok;
1438 			int i;
1439 			char prefix=' ';
1440 
1441 			vtok=get_token();
1442 			if((vtok==T_END)||(vtok==T_EOF)) break;
1443 			fractional_timescale_fix(GLOBALS->yytext_vcd_recoder_c_3);
1444 			GLOBALS->time_scale=atoi_64(GLOBALS->yytext_vcd_recoder_c_3);
1445 			if(!GLOBALS->time_scale) GLOBALS->time_scale=1;
1446 			for(i=0;i<GLOBALS->yylen_vcd_recoder_c_3;i++)
1447 				{
1448 				if((GLOBALS->yytext_vcd_recoder_c_3[i]<'0')||(GLOBALS->yytext_vcd_recoder_c_3[i]>'9'))
1449 					{
1450 					prefix=GLOBALS->yytext_vcd_recoder_c_3[i];
1451 					break;
1452 					}
1453 				}
1454 			if(prefix==' ')
1455 				{
1456 				vtok=get_token();
1457 				if((vtok==T_END)||(vtok==T_EOF)) break;
1458 				prefix=GLOBALS->yytext_vcd_recoder_c_3[0];
1459 				}
1460 			switch(prefix)
1461 				{
1462 				case ' ':
1463 				case 'm':
1464 				case 'u':
1465 				case 'n':
1466 				case 'p':
1467 				case 'f':
1468 				case 'a':
1469 				case 'z':
1470 					GLOBALS->time_dimension=prefix;
1471 					break;
1472 				case 's':
1473 					GLOBALS->time_dimension=' ';
1474 					break;
1475 				default:	/* unknown */
1476 					GLOBALS->time_dimension='n';
1477 					break;
1478 				}
1479 
1480 			DEBUG(fprintf(stderr,"TIMESCALE: "TTFormat" %cs\n",GLOBALS->time_scale, GLOBALS->time_dimension));
1481 			sync_end(NULL);
1482 			}
1483 			break;
1484 		case T_SCOPE:
1485 			T_GET;
1486 				{
1487 				switch(GLOBALS->yytext_vcd_recoder_c_3[0])
1488 					{
1489 					case 'm':	ttype = TREE_VCD_ST_MODULE; break;
1490 					case 't':	ttype = TREE_VCD_ST_TASK; break;
1491 					case 'f':	ttype = (GLOBALS->yytext_vcd_recoder_c_3[1] == 'u') ? TREE_VCD_ST_FUNCTION : TREE_VCD_ST_FORK; break;
1492 					case 'b':	ttype = TREE_VCD_ST_BEGIN; break;
1493 					case 'g':       ttype = TREE_VCD_ST_GENERATE; break;
1494 					case 's':       ttype = TREE_VCD_ST_STRUCT; break;
1495 					case 'u':       ttype = TREE_VCD_ST_UNION; break;
1496 					case 'c':       ttype = TREE_VCD_ST_CLASS; break;
1497 					case 'i':       ttype = TREE_VCD_ST_INTERFACE; break;
1498 					case 'p':       ttype = (GLOBALS->yytext_vcd_recoder_c_3[1] == 'r') ? TREE_VCD_ST_PROGRAM : TREE_VCD_ST_PACKAGE; break;
1499 
1500 					case 'v':	{
1501 							char *vht = GLOBALS->yytext_vcd_recoder_c_3;
1502 				                       	if(!strncmp(vht, "vhdl_", 5))
1503                                 				{
1504 				                                switch(vht[5])
1505 				                                        {
1506 				                                        case 'a':       ttype = TREE_VHDL_ST_ARCHITECTURE; break;
1507 				                                        case 'r':       ttype = TREE_VHDL_ST_RECORD; break;
1508 				                                        case 'b':       ttype = TREE_VHDL_ST_BLOCK; break;
1509 				                                        case 'g':       ttype = TREE_VHDL_ST_GENERATE; break;
1510 				                                        case 'i':       ttype = TREE_VHDL_ST_GENIF; break;
1511 				                                        case 'f':       ttype = (vht[6] == 'u') ? TREE_VHDL_ST_FUNCTION : TREE_VHDL_ST_GENFOR; break;
1512 				                                        case 'p':       ttype = (!strncmp(vht+6, "roces", 5)) ? TREE_VHDL_ST_PROCESS: TREE_VHDL_ST_PROCEDURE; break;
1513 				                                        default:        ttype = TREE_UNKNOWN; break;
1514 				                                        }
1515 								}
1516 								else
1517 								{
1518 								ttype = TREE_UNKNOWN;
1519 								}
1520                                 			}
1521 							break;
1522 
1523 					default:	ttype = TREE_UNKNOWN;
1524 							break;
1525 					}
1526 				}
1527 			T_GET;
1528 			if(tok==T_STRING)
1529 				{
1530 				struct slist *s;
1531 				s=(struct slist *)calloc_2(1,sizeof(struct slist));
1532 				s->len=GLOBALS->yylen_vcd_recoder_c_3;
1533 				s->str=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+1);
1534 				strcpy(s->str, GLOBALS->yytext_vcd_recoder_c_3);
1535 				s->mod_tree_parent = GLOBALS->mod_tree_parent;
1536 
1537 				allocate_and_decorate_module_tree_node(ttype, GLOBALS->yytext_vcd_recoder_c_3, NULL, GLOBALS->yylen_vcd_recoder_c_3, 0, 0, 0);
1538 
1539 				if(GLOBALS->slistcurr)
1540 					{
1541 					GLOBALS->slistcurr->next=s;
1542 					GLOBALS->slistcurr=s;
1543 					}
1544 					else
1545 					{
1546 					GLOBALS->slistcurr=GLOBALS->slistroot=s;
1547 					}
1548 
1549 				build_slisthier();
1550 				DEBUG(fprintf(stderr, "SCOPE: %s\n",GLOBALS->slisthier));
1551 				}
1552 			sync_end(NULL);
1553 			break;
1554 		case T_UPSCOPE:
1555 			if(GLOBALS->slistroot)
1556 				{
1557 				struct slist *s;
1558 
1559 				GLOBALS->mod_tree_parent = GLOBALS->slistcurr->mod_tree_parent;
1560 				s=GLOBALS->slistroot;
1561 				if(!s->next)
1562 					{
1563 					free_2(s->str);
1564 					free_2(s);
1565 					GLOBALS->slistroot=GLOBALS->slistcurr=NULL;
1566 					}
1567 				else
1568 				for(;;)
1569 					{
1570 					if(!s->next->next)
1571 						{
1572 						free_2(s->next->str);
1573 						free_2(s->next);
1574 						s->next=NULL;
1575 						GLOBALS->slistcurr=s;
1576 						break;
1577 						}
1578 					s=s->next;
1579 					}
1580 				build_slisthier();
1581 				DEBUG(fprintf(stderr, "SCOPE: %s\n",GLOBALS->slisthier));
1582 				}
1583 				else
1584 				{
1585 				GLOBALS->mod_tree_parent = NULL;
1586 				}
1587 			sync_end(NULL);
1588 			break;
1589 		case T_VAR:
1590 			if((GLOBALS->header_over_vcd_recoder_c_3)&&(0))
1591 			{
1592 			fprintf(stderr,"$VAR encountered after $ENDDEFINITIONS near byte %d.  VCD is malformed, exiting.\n",
1593 				(int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3)));
1594 			vcd_exit(255);
1595 			}
1596 			else
1597 			{
1598 			int vtok;
1599 			struct vcdsymbol *v=NULL;
1600 
1601 			GLOBALS->var_prevch_vcd_recoder_c_3=0;
1602                         if(GLOBALS->varsplit_vcd_recoder_c_3)
1603                                 {
1604                                 free_2(GLOBALS->varsplit_vcd_recoder_c_3);
1605                                 GLOBALS->varsplit_vcd_recoder_c_3=NULL;
1606                                 }
1607 			vtok=get_vartoken(1);
1608 			if(vtok>V_STRINGTYPE) goto bail;
1609 
1610 			v=(struct vcdsymbol *)calloc_2(1,sizeof(struct vcdsymbol));
1611 			v->vartype=vtok;
1612 			v->msi=v->lsi=GLOBALS->vcd_explicit_zero_subscripts; /* indicate [un]subscripted status */
1613 
1614 			if(vtok==V_PORT)
1615 				{
1616 				vtok=get_vartoken(1);
1617 				if(vtok==V_STRING)
1618 					{
1619 					v->size=atoi_64(GLOBALS->yytext_vcd_recoder_c_3);
1620 					if(!v->size) v->size=1;
1621 					}
1622 					else
1623 					if(vtok==V_LB)
1624 					{
1625 					vtok=get_vartoken(1);
1626 					if(vtok==V_END) goto err;
1627 					if(vtok!=V_STRING) goto err;
1628 					v->msi=atoi_64(GLOBALS->yytext_vcd_recoder_c_3);
1629 					vtok=get_vartoken(0);
1630 					if(vtok==V_RB)
1631 						{
1632 						v->lsi=v->msi;
1633 						v->size=1;
1634 						}
1635 						else
1636 						{
1637 						if(vtok!=V_COLON) goto err;
1638 						vtok=get_vartoken(0);
1639 						if(vtok!=V_STRING) goto err;
1640 						v->lsi=atoi_64(GLOBALS->yytext_vcd_recoder_c_3);
1641 						vtok=get_vartoken(0);
1642 						if(vtok!=V_RB) goto err;
1643 
1644 						if(v->msi>v->lsi)
1645 							{
1646 							v->size=v->msi-v->lsi+1;
1647 							}
1648 							else
1649 							{
1650 							v->size=v->lsi-v->msi+1;
1651 							}
1652 						}
1653 					}
1654 					else goto err;
1655 
1656 				vtok=get_strtoken();
1657 				if(vtok==V_END) goto err;
1658 				v->id=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+1);
1659 				strcpy(v->id, GLOBALS->yytext_vcd_recoder_c_3);
1660                                 v->nid=vcdid_hash(GLOBALS->yytext_vcd_recoder_c_3,GLOBALS->yylen_vcd_recoder_c_3);
1661 
1662 		                if(v->nid == (GLOBALS->vcd_hash_max+1))
1663                 		        {
1664 		                        GLOBALS->vcd_hash_max = v->nid;
1665 		                        }
1666 		                else
1667 		                if((v->nid>0)&&(v->nid<=GLOBALS->vcd_hash_max))
1668 		                        {
1669 		                        /* general case with aliases */
1670 		                        }
1671 		                else
1672 		                        {
1673 		                        GLOBALS->vcd_hash_kill = 1;
1674 		                        }
1675 
1676                                 if(v->nid < GLOBALS->vcd_minid_vcd_recoder_c_3) GLOBALS->vcd_minid_vcd_recoder_c_3 = v->nid;
1677                                 if(v->nid > GLOBALS->vcd_maxid_vcd_recoder_c_3) GLOBALS->vcd_maxid_vcd_recoder_c_3 = v->nid;
1678 
1679 				vtok=get_vartoken(0);
1680 				if(vtok!=V_STRING) goto err;
1681 				if(GLOBALS->slisthier_len)
1682 					{
1683 					v->name=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_recoder_c_3+1);
1684 					strcpy(v->name,GLOBALS->slisthier);
1685 					strcpy(v->name+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter);
1686 					if(GLOBALS->alt_hier_delimeter)
1687 						{
1688 						strcpy_vcdalt(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_recoder_c_3,GLOBALS->alt_hier_delimeter);
1689 						}
1690 						else
1691 						{
1692 						if((strcpy_delimfix(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_recoder_c_3)) && (GLOBALS->yytext_vcd_recoder_c_3[0] != '\\'))
1693 							{
1694 							char *sd=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_recoder_c_3+2);
1695 							strcpy(sd,GLOBALS->slisthier);
1696 							strcpy(sd+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter);
1697 							sd[GLOBALS->slisthier_len+1] = '\\';
1698 							strcpy(sd+GLOBALS->slisthier_len+2,v->name+GLOBALS->slisthier_len+1);
1699 							free_2(v->name);
1700 							v->name = sd;
1701 							}
1702 						}
1703 					}
1704 					else
1705 					{
1706 					v->name=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+1);
1707 					if(GLOBALS->alt_hier_delimeter)
1708 						{
1709 						strcpy_vcdalt(v->name,GLOBALS->yytext_vcd_recoder_c_3,GLOBALS->alt_hier_delimeter);
1710 						}
1711 						else
1712 						{
1713 						if((strcpy_delimfix(v->name,GLOBALS->yytext_vcd_recoder_c_3)) && (GLOBALS->yytext_vcd_recoder_c_3[0] != '\\'))
1714 							{
1715 							char *sd=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+2);
1716 							sd[0] = '\\';
1717 							strcpy(sd+1,v->name);
1718 							free_2(v->name);
1719 							v->name = sd;
1720 							}
1721 						}
1722 					}
1723 
1724                                 if(GLOBALS->pv_vcd_recoder_c_3)
1725                                         {
1726                                         if(!strcmp(GLOBALS->prev_hier_uncompressed_name,v->name) && !disable_autocoalesce && (!strchr(v->name, '\\')))
1727                                                 {
1728                                                 GLOBALS->pv_vcd_recoder_c_3->chain=v;
1729                                                 v->root=GLOBALS->rootv_vcd_recoder_c_3;
1730                                                 if(GLOBALS->pv_vcd_recoder_c_3==GLOBALS->rootv_vcd_recoder_c_3) GLOBALS->pv_vcd_recoder_c_3->root=GLOBALS->rootv_vcd_recoder_c_3;
1731                                                 }
1732                                                 else
1733                                                 {
1734                                                 GLOBALS->rootv_vcd_recoder_c_3=v;
1735                                                 }
1736 
1737 					free_2(GLOBALS->prev_hier_uncompressed_name);
1738                                         }
1739 					else
1740 					{
1741 					GLOBALS->rootv_vcd_recoder_c_3=v;
1742 					}
1743 
1744                                 GLOBALS->pv_vcd_recoder_c_3=v;
1745 				GLOBALS->prev_hier_uncompressed_name = strdup_2(v->name);
1746 				}
1747 				else	/* regular vcd var, not an evcd port var */
1748 				{
1749 				vtok=get_vartoken(1);
1750 				if(vtok==V_END) goto err;
1751 				v->size=atoi_64(GLOBALS->yytext_vcd_recoder_c_3);
1752 				vtok=get_strtoken();
1753 				if(vtok==V_END) goto err;
1754 				v->id=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+1);
1755 				strcpy(v->id, GLOBALS->yytext_vcd_recoder_c_3);
1756                                 v->nid=vcdid_hash(GLOBALS->yytext_vcd_recoder_c_3,GLOBALS->yylen_vcd_recoder_c_3);
1757 
1758                                 if(v->nid == (GLOBALS->vcd_hash_max+1))
1759                                         {
1760                                         GLOBALS->vcd_hash_max = v->nid;
1761                                         }
1762                                 else
1763                                 if((v->nid>0)&&(v->nid<=GLOBALS->vcd_hash_max))
1764                                         {
1765                                         /* general case with aliases */
1766                                         }
1767                                 else
1768                                         {
1769                                         GLOBALS->vcd_hash_kill = 1;
1770                                         }
1771 
1772                                 if(v->nid < GLOBALS->vcd_minid_vcd_recoder_c_3) GLOBALS->vcd_minid_vcd_recoder_c_3 = v->nid;
1773                                 if(v->nid > GLOBALS->vcd_maxid_vcd_recoder_c_3) GLOBALS->vcd_maxid_vcd_recoder_c_3 = v->nid;
1774 
1775 				vtok=get_vartoken(0);
1776 				if(vtok!=V_STRING) goto err;
1777 
1778 				if(GLOBALS->slisthier_len)
1779 					{
1780 					v->name=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_recoder_c_3+1);
1781 					strcpy(v->name,GLOBALS->slisthier);
1782 					strcpy(v->name+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter);
1783 					if(GLOBALS->alt_hier_delimeter)
1784 						{
1785 						strcpy_vcdalt(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_recoder_c_3,GLOBALS->alt_hier_delimeter);
1786 						}
1787 						else
1788 						{
1789 						if((strcpy_delimfix(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_recoder_c_3)) && (GLOBALS->yytext_vcd_recoder_c_3[0] != '\\'))
1790 							{
1791                                                         char *sd=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_recoder_c_3+2);
1792                                                         strcpy(sd,GLOBALS->slisthier);
1793                                                         strcpy(sd+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter);
1794                                                         sd[GLOBALS->slisthier_len+1] = '\\';
1795                                                         strcpy(sd+GLOBALS->slisthier_len+2,v->name+GLOBALS->slisthier_len+1);
1796                                                         free_2(v->name);
1797                                                         v->name = sd;
1798 							}
1799 						}
1800 					}
1801 					else
1802 					{
1803 					v->name=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+1);
1804 					if(GLOBALS->alt_hier_delimeter)
1805 						{
1806 						strcpy_vcdalt(v->name,GLOBALS->yytext_vcd_recoder_c_3,GLOBALS->alt_hier_delimeter);
1807 						}
1808 						else
1809 						{
1810                                                 if((strcpy_delimfix(v->name,GLOBALS->yytext_vcd_recoder_c_3)) && (GLOBALS->yytext_vcd_recoder_c_3[0] != '\\'))
1811                                                         {
1812                                                         char *sd=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+2);
1813                                                         sd[0] = '\\';
1814                                                         strcpy(sd+1,v->name);
1815                                                         free_2(v->name);
1816                                                         v->name = sd;
1817                                                         }
1818 						}
1819 					}
1820 
1821                                 if(GLOBALS->pv_vcd_recoder_c_3)
1822                                         {
1823                                         if(!strcmp(GLOBALS->prev_hier_uncompressed_name,v->name))
1824                                                 {
1825                                                 GLOBALS->pv_vcd_recoder_c_3->chain=v;
1826                                                 v->root=GLOBALS->rootv_vcd_recoder_c_3;
1827                                                 if(GLOBALS->pv_vcd_recoder_c_3==GLOBALS->rootv_vcd_recoder_c_3) GLOBALS->pv_vcd_recoder_c_3->root=GLOBALS->rootv_vcd_recoder_c_3;
1828                                                 }
1829                                                 else
1830                                                 {
1831                                                 GLOBALS->rootv_vcd_recoder_c_3=v;
1832                                                 }
1833 
1834 					free_2(GLOBALS->prev_hier_uncompressed_name);
1835                                         }
1836 					else
1837 					{
1838 					GLOBALS->rootv_vcd_recoder_c_3=v;
1839 					}
1840                                 GLOBALS->pv_vcd_recoder_c_3=v;
1841 				GLOBALS->prev_hier_uncompressed_name = strdup_2(v->name);
1842 
1843 				vtok=get_vartoken(1);
1844 				if(vtok==V_END) goto dumpv;
1845 				if(vtok!=V_LB) goto err;
1846 				vtok=get_vartoken(0);
1847 				if(vtok!=V_STRING) goto err;
1848 				v->msi=atoi_64(GLOBALS->yytext_vcd_recoder_c_3);
1849 				vtok=get_vartoken(0);
1850 				if(vtok==V_RB)
1851 					{
1852 					v->lsi=v->msi;
1853 					goto dumpv;
1854 					}
1855 				if(vtok!=V_COLON) goto err;
1856 				vtok=get_vartoken(0);
1857 				if(vtok!=V_STRING) goto err;
1858 				v->lsi=atoi_64(GLOBALS->yytext_vcd_recoder_c_3);
1859 				vtok=get_vartoken(0);
1860 				if(vtok!=V_RB) goto err;
1861 				}
1862 
1863 			dumpv:
1864 			if(v->size == 0)
1865 				{
1866 				if(v->vartype != V_EVENT)
1867 					{
1868 					if(v->vartype != V_STRINGTYPE)
1869 						{
1870 						v->vartype = V_REAL;
1871 						}
1872 					}
1873 					else
1874 					{
1875 					v->size = 1;
1876 					}
1877 
1878 				} /* MTI fix */
1879 
1880 
1881 			if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE))
1882 				{
1883 				v->size=1;		/* override any data we parsed in */
1884 				v->msi=v->lsi=0;
1885 				}
1886 			else
1887 			if((v->size>1)&&(v->msi<=0)&&(v->lsi<=0))
1888 				{
1889 				if(v->vartype==V_EVENT)
1890 					{
1891 					v->size=1;
1892 					}
1893 					else
1894 					{
1895 					/* any criteria for the direction here? */
1896 					v->msi=v->size-1;
1897 					v->lsi=0;
1898 					}
1899 				}
1900 			else
1901 			if((v->msi>v->lsi)&&((v->msi-v->lsi+1)!=v->size))
1902 				{
1903 				if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER))
1904 					{
1905 					if((v->msi-v->lsi+1) > v->size) /* if() is 2d add */
1906 						{
1907 						v->msi = v->size-1; v->lsi = 0;
1908 						}
1909 					/* all this formerly was goto err; */
1910 					}
1911 					else
1912 					{
1913 					v->size=v->msi-v->lsi+1;
1914 					}
1915 				}
1916 			else
1917 			if((v->lsi>=v->msi)&&((v->lsi-v->msi+1)!=v->size))
1918 				{
1919 				if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER))
1920 					{
1921 					if((v->lsi-v->msi+1) > v->size) /* if() is 2d add */
1922 						{
1923 						v->lsi = v->size-1; v->msi = 0;
1924 						}
1925 					/* all this formerly was goto err; */
1926 					}
1927 					else
1928 					{
1929 					v->size=v->lsi-v->msi+1;
1930 					}
1931 				}
1932 
1933 			/* initial conditions */
1934 			v->narray=(struct Node **)calloc_2(1,sizeof(struct Node *));
1935 			v->narray[0]=(struct Node *)calloc_2(1,sizeof(struct Node));
1936 			v->narray[0]->head.time=-1;
1937 			v->narray[0]->head.v.h_val=AN_X;
1938 
1939 			if(!GLOBALS->vcdsymroot_vcd_recoder_c_3)
1940 				{
1941 				GLOBALS->vcdsymroot_vcd_recoder_c_3=GLOBALS->vcdsymcurr_vcd_recoder_c_3=v;
1942 				}
1943 				else
1944 				{
1945 				GLOBALS->vcdsymcurr_vcd_recoder_c_3->next=v;
1946 				GLOBALS->vcdsymcurr_vcd_recoder_c_3=v;
1947 				}
1948 			GLOBALS->numsyms_vcd_recoder_c_3++;
1949 
1950 			if(GLOBALS->vcd_save_handle)
1951 				{
1952 				if(v->msi==v->lsi)
1953 					{
1954 					if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE))
1955 						{
1956 						fprintf(GLOBALS->vcd_save_handle,"%s\n",v->name);
1957 						}
1958 						else
1959 						{
1960 						if(v->msi>=0)
1961 							{
1962 							if(!GLOBALS->vcd_explicit_zero_subscripts)
1963 								fprintf(GLOBALS->vcd_save_handle,"%s%c%d\n",v->name,GLOBALS->hier_delimeter,v->msi);
1964 								else
1965 								fprintf(GLOBALS->vcd_save_handle,"%s[%d]\n",v->name,v->msi);
1966 							}
1967 							else
1968 							{
1969 							fprintf(GLOBALS->vcd_save_handle,"%s\n",v->name);
1970 							}
1971 						}
1972 					}
1973 					else
1974 					{
1975 					fprintf(GLOBALS->vcd_save_handle,"%s[%d:%d]\n",v->name,v->msi,v->lsi);
1976 					}
1977 				}
1978 
1979 			goto bail;
1980 			err:
1981 			if(v)
1982 				{
1983 				GLOBALS->error_count_vcd_recoder_c_3++;
1984 				if(v->name)
1985 					{
1986 					fprintf(stderr, "Near byte %d, $VAR parse error encountered with '%s'\n", (int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3)), v->name);
1987 					free_2(v->name);
1988 					}
1989 					else
1990 					{
1991 					fprintf(stderr, "Near byte %d, $VAR parse error encountered\n", (int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3)));
1992 					}
1993 				if(v->id) free_2(v->id);
1994 				free_2(v); v=NULL;
1995 				GLOBALS->pv_vcd_recoder_c_3 = NULL;
1996 				}
1997 
1998 			bail:
1999 			if(vtok!=V_END) sync_end(NULL);
2000 			break;
2001 			}
2002 		case T_ENDDEFINITIONS:
2003 			GLOBALS->header_over_vcd_recoder_c_3=1;	/* do symbol table management here */
2004 			create_sorted_table();
2005 			if((!GLOBALS->sorted_vcd_recoder_c_3)&&(!GLOBALS->indexed_vcd_recoder_c_3))
2006 				{
2007 				fprintf(stderr, "No symbols in VCD file..nothing to do!\n");
2008 				vcd_exit(255);
2009 				}
2010 			if(GLOBALS->error_count_vcd_recoder_c_3)
2011 				{
2012 				fprintf(stderr, "\n%d VCD parse errors encountered, exiting.\n", GLOBALS->error_count_vcd_recoder_c_3);
2013 				vcd_exit(255);
2014 				}
2015 
2016 			if(GLOBALS->use_fastload == VCD_FSL_READ)
2017 				{
2018 				read_fastload_body();
2019 				fprintf(stderr, "VCDLOAD | Using fastload file.\n");
2020 				return;
2021 				}
2022 
2023 			break;
2024 		case T_STRING:
2025 			if(!GLOBALS->header_over_vcd_recoder_c_3)
2026 				{
2027 				GLOBALS->header_over_vcd_recoder_c_3=1;	/* do symbol table management here */
2028 				create_sorted_table();
2029 				if((!GLOBALS->sorted_vcd_recoder_c_3)&&(!GLOBALS->indexed_vcd_recoder_c_3)) break;
2030 				}
2031 				{
2032 				/* catchall for events when header over */
2033 				if(GLOBALS->yytext_vcd_recoder_c_3[0]=='#')
2034 					{
2035 					TimeType tim;
2036 					TimeType *tt;
2037 
2038 					tim=atoi_64(GLOBALS->yytext_vcd_recoder_c_3+1);
2039 
2040 					if(GLOBALS->start_time_vcd_recoder_c_3<0)
2041 						{
2042 						GLOBALS->start_time_vcd_recoder_c_3=tim;
2043 
2044 						if(GLOBALS->time_vlist_vcd_recoder_write)
2045 							{
2046 							vlist_packer_emit_utt((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, tim);
2047 							}
2048 						}
2049 						else
2050 						{
2051 /* backtracking fix */
2052 						if(tim < GLOBALS->current_time_vcd_recoder_c_3)
2053 							{
2054 							if(!GLOBALS->vcd_already_backtracked)
2055 								{
2056 								GLOBALS->vcd_already_backtracked = 1;
2057 								fprintf(stderr, "VCDLOAD | Time backtracking detected in VCD file!\n");
2058 								}
2059 							}
2060 #if 0
2061 						if(tim < GLOBALS->current_time_vcd_recoder_c_3) /* avoid backtracking time counts which can happen on malformed files */
2062 							{
2063 							tim = GLOBALS->current_time_vcd_recoder_c_3;
2064 							}
2065 #endif
2066 
2067 						if(GLOBALS->time_vlist_vcd_recoder_write)
2068 							{
2069 							vlist_packer_emit_utt((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, tim - GLOBALS->current_time_vcd_recoder_c_3);
2070 							}
2071 						}
2072 
2073 					GLOBALS->current_time_vcd_recoder_c_3=tim;
2074 					if(GLOBALS->end_time_vcd_recoder_c_3<tim) GLOBALS->end_time_vcd_recoder_c_3=tim;	/* in case of malformed vcd files */
2075 					DEBUG(fprintf(stderr,"#"TTFormat"\n",tim));
2076 
2077 					tt = vlist_alloc(&GLOBALS->time_vlist_vcd_recoder_c_1, 0);
2078 					*tt = tim;
2079 					GLOBALS->time_vlist_count_vcd_recoder_c_1++;
2080 					}
2081 					else
2082 					{
2083 					if(GLOBALS->time_vlist_count_vcd_recoder_c_1)
2084 						{
2085 						/* OK, otherwise fix for System C which doesn't emit time zero... */
2086 						}
2087 						else
2088 						{
2089 						TimeType tim = LLDescriptor(0);
2090 						TimeType *tt;
2091 
2092 						GLOBALS->start_time_vcd_recoder_c_3=GLOBALS->current_time_vcd_recoder_c_3=GLOBALS->end_time_vcd_recoder_c_3=tim;
2093 
2094 						if(GLOBALS->time_vlist_vcd_recoder_write)
2095 							{
2096 							vlist_packer_emit_utt((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, tim);
2097 							}
2098 
2099 						tt = vlist_alloc(&GLOBALS->time_vlist_vcd_recoder_c_1, 0);
2100 						*tt = tim;
2101 						GLOBALS->time_vlist_count_vcd_recoder_c_1=1;
2102 						}
2103 					parse_valuechange();
2104 					}
2105 				}
2106 			break;
2107 		case T_DUMPALL:	/* dump commands modify vals anyway so */
2108 		case T_DUMPPORTSALL:
2109 			break;	/* just loop through..                 */
2110 		case T_DUMPOFF:
2111 		case T_DUMPPORTSOFF:
2112 			GLOBALS->dumping_off_vcd_recoder_c_3=1;
2113                         /* if((!GLOBALS->blackout_regions)||((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart<=GLOBALS->blackout_regions->bend))) : remove redundant condition */
2114                         if((!GLOBALS->blackout_regions)||(GLOBALS->blackout_regions->bstart<=GLOBALS->blackout_regions->bend))
2115 				{
2116 				struct blackout_region_t *bt = calloc_2(1, sizeof(struct blackout_region_t));
2117 
2118 				bt->bstart = GLOBALS->current_time_vcd_recoder_c_3;
2119 				bt->next = GLOBALS->blackout_regions;
2120 				GLOBALS->blackout_regions = bt;
2121 				}
2122 			break;
2123 		case T_DUMPON:
2124 		case T_DUMPPORTSON:
2125 			GLOBALS->dumping_off_vcd_recoder_c_3=0;
2126 			if((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart>GLOBALS->blackout_regions->bend))
2127 				{
2128 				GLOBALS->blackout_regions->bend = GLOBALS->current_time_vcd_recoder_c_3;
2129 				}
2130 			break;
2131 		case T_DUMPVARS:
2132 		case T_DUMPPORTS:
2133 			if(GLOBALS->current_time_vcd_recoder_c_3<0)
2134 				{ GLOBALS->start_time_vcd_recoder_c_3=GLOBALS->current_time_vcd_recoder_c_3=GLOBALS->end_time_vcd_recoder_c_3=0; }
2135 			break;
2136 		case T_VCDCLOSE:
2137 			sync_end("VCDCLOSE:");
2138 			break;	/* next token will be '#' time related followed by $end */
2139 		case T_END:	/* either closure for dump commands or */
2140 			break;	/* it's spurious                       */
2141 		case T_UNKNOWN_KEY:
2142 			sync_end(NULL);	/* skip over unknown keywords */
2143 			break;
2144 		case T_EOF:
2145 			if((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart>GLOBALS->blackout_regions->bend))
2146 				{
2147 				GLOBALS->blackout_regions->bend = GLOBALS->current_time_vcd_recoder_c_3;
2148 				}
2149 
2150 			GLOBALS->pv_vcd_recoder_c_3 = NULL;
2151 			if(GLOBALS->prev_hier_uncompressed_name) { free_2(GLOBALS->prev_hier_uncompressed_name); GLOBALS->prev_hier_uncompressed_name = NULL; }
2152 
2153 			return;
2154 		default:
2155 			DEBUG(fprintf(stderr,"UNKNOWN TOKEN\n"));
2156 		}
2157 	}
2158 }
2159 
2160 
2161 /*******************************************************************************/
2162 
add_histent(TimeType tim,struct Node * n,char ch,int regadd,char * vector)2163 void add_histent(TimeType tim, struct Node *n, char ch, int regadd, char *vector)
2164 {
2165 struct HistEnt *he;
2166 char heval;
2167 
2168 if(!vector)
2169 {
2170 if(!n->curr)
2171 	{
2172 	he=histent_calloc();
2173         he->time=-1;
2174         he->v.h_val=AN_X;
2175 
2176 	n->curr=he;
2177 	n->head.next=he;
2178 
2179 	add_histent(tim,n,ch,regadd, vector);
2180 	}
2181 	else
2182 	{
2183 	if(regadd) { tim*=(GLOBALS->time_scale); }
2184 
2185 	if(ch=='0')              heval=AN_0; else
2186 	if(ch=='1')              heval=AN_1; else
2187         if((ch=='x')||(ch=='X')) heval=AN_X; else
2188         if((ch=='z')||(ch=='Z')) heval=AN_Z; else
2189         if((ch=='h')||(ch=='H')) heval=AN_H; else
2190         if((ch=='u')||(ch=='U')) heval=AN_U; else
2191         if((ch=='w')||(ch=='W')) heval=AN_W; else
2192         if((ch=='l')||(ch=='L')) heval=AN_L; else
2193         /* if(ch=='-') */        heval=AN_DASH;		/* default */
2194 
2195 	if((n->curr->v.h_val!=heval)||(tim==GLOBALS->start_time_vcd_recoder_c_3)||(n->vartype==ND_VCD_EVENT)||(GLOBALS->vcd_preserve_glitches)) /* same region == go skip */
2196         	{
2197 		if(n->curr->time==tim)
2198 			{
2199 			DEBUG(printf("Warning: Glitch at time ["TTFormat"] Signal [%p], Value [%c->%c].\n",
2200 				tim, n, AN_STR[n->curr->v.h_val], ch));
2201 			n->curr->v.h_val=heval;		/* we have a glitch! */
2202 
2203 			GLOBALS->num_glitches_vcd_recoder_c_4++;
2204 			if(!(n->curr->flags&HIST_GLITCH))
2205 				{
2206 				n->curr->flags|=HIST_GLITCH;	/* set the glitch flag */
2207 				GLOBALS->num_glitch_regions_vcd_recoder_c_4++;
2208 				}
2209 			}
2210 			else
2211 			{
2212                 	he=histent_calloc();
2213                 	he->time=tim;
2214                 	he->v.h_val=heval;
2215 
2216                 	n->curr->next=he;
2217 			if(n->curr->v.h_val==heval)
2218 				{
2219 				n->curr->flags|=HIST_GLITCH;    /* set the glitch flag */
2220 				GLOBALS->num_glitch_regions_vcd_recoder_c_4++;
2221 				}
2222 			n->curr=he;
2223                 	GLOBALS->regions+=regadd;
2224 			}
2225                 }
2226        }
2227 }
2228 else
2229 {
2230 switch(ch)
2231 	{
2232 	case 's': /* string */
2233 	{
2234 	if(!n->curr)
2235 		{
2236 		he=histent_calloc();
2237 		he->flags=(HIST_STRING|HIST_REAL);
2238 	        he->time=-1;
2239 	        he->v.h_vector=NULL;
2240 
2241 		n->curr=he;
2242 		n->head.next=he;
2243 
2244 		add_histent(tim,n,ch,regadd, vector);
2245 		}
2246 		else
2247 		{
2248 		if(regadd) { tim*=(GLOBALS->time_scale); }
2249 
2250 			if(n->curr->time==tim)
2251 				{
2252 				DEBUG(printf("Warning: String Glitch at time ["TTFormat"] Signal [%p].\n",
2253 					tim, n));
2254 				if(n->curr->v.h_vector) free_2(n->curr->v.h_vector);
2255 				n->curr->v.h_vector=vector;		/* we have a glitch! */
2256 
2257 				GLOBALS->num_glitches_vcd_recoder_c_4++;
2258 				if(!(n->curr->flags&HIST_GLITCH))
2259 					{
2260 					n->curr->flags|=HIST_GLITCH;	/* set the glitch flag */
2261 					GLOBALS->num_glitch_regions_vcd_recoder_c_4++;
2262 					}
2263 				}
2264 				else
2265 				{
2266 	                	he=histent_calloc();
2267 				he->flags=(HIST_STRING|HIST_REAL);
2268 	                	he->time=tim;
2269 	                	he->v.h_vector=vector;
2270 
2271 	                	n->curr->next=he;
2272 				n->curr=he;
2273 	                	GLOBALS->regions+=regadd;
2274 				}
2275 	       }
2276 	break;
2277 	}
2278 	case 'g': /* real number */
2279 	{
2280 	if(!n->curr)
2281 		{
2282 		he=histent_calloc();
2283 		he->flags=HIST_REAL;
2284 	        he->time=-1;
2285 #ifdef WAVE_HAS_H_DOUBLE
2286                 he->v.h_double = strtod("NaN", NULL);
2287 #else
2288 	        he->v.h_vector=NULL;
2289 #endif
2290 
2291 		n->curr=he;
2292 		n->head.next=he;
2293 
2294 		add_histent(tim,n,ch,regadd, vector);
2295 		}
2296 		else
2297 		{
2298 		if(regadd) { tim*=(GLOBALS->time_scale); }
2299 
2300 		if(
2301 #ifdef WAVE_HAS_H_DOUBLE
2302                   (vector&&(n->curr->v.h_double!=*(double *)vector))
2303 #else
2304 		  (n->curr->v.h_vector&&vector&&(*(double *)n->curr->v.h_vector!=*(double *)vector))
2305 #endif
2306 			||(tim==GLOBALS->start_time_vcd_recoder_c_3)
2307 #ifndef WAVE_HAS_H_DOUBLE
2308 			||(!n->curr->v.h_vector)
2309 #endif
2310 			||(GLOBALS->vcd_preserve_glitches)||(GLOBALS->vcd_preserve_glitches_real)
2311 			) /* same region == go skip */
2312 	        	{
2313 			if(n->curr->time==tim)
2314 				{
2315 				DEBUG(printf("Warning: Real number Glitch at time ["TTFormat"] Signal [%p].\n",
2316 					tim, n));
2317 #ifdef WAVE_HAS_H_DOUBLE
2318                                 n->curr->v.h_double = *((double *)vector);
2319 #else
2320 				if(n->curr->v.h_vector) free_2(n->curr->v.h_vector);
2321 				n->curr->v.h_vector=vector;		/* we have a glitch! */
2322 #endif
2323 				GLOBALS->num_glitches_vcd_recoder_c_4++;
2324 				if(!(n->curr->flags&HIST_GLITCH))
2325 					{
2326 					n->curr->flags|=HIST_GLITCH;	/* set the glitch flag */
2327 					GLOBALS->num_glitch_regions_vcd_recoder_c_4++;
2328 					}
2329 				}
2330 				else
2331 				{
2332 	                	he=histent_calloc();
2333 				he->flags=HIST_REAL;
2334 	                	he->time=tim;
2335 #ifdef WAVE_HAS_H_DOUBLE
2336 				he->v.h_double = *((double *)vector);
2337 #else
2338 	                	he->v.h_vector=vector;
2339 #endif
2340 	                	n->curr->next=he;
2341 				n->curr=he;
2342 	                	GLOBALS->regions+=regadd;
2343 				}
2344 	                }
2345 			else
2346 			{
2347 #ifndef WAVE_HAS_H_DOUBLE
2348 			free_2(vector);
2349 #endif
2350 			}
2351 #ifdef WAVE_HAS_H_DOUBLE
2352 	        free_2(vector);
2353 #endif
2354 	       }
2355 	break;
2356 	}
2357 	default:
2358 	{
2359 	if(!n->curr)
2360 		{
2361 		he=histent_calloc();
2362 	        he->time=-1;
2363 	        he->v.h_vector=NULL;
2364 
2365 		n->curr=he;
2366 		n->head.next=he;
2367 
2368 		add_histent(tim,n,ch,regadd, vector);
2369 		}
2370 		else
2371 		{
2372 		if(regadd) { tim*=(GLOBALS->time_scale); }
2373 
2374 		if(
2375 		  (n->curr->v.h_vector&&vector&&(strcmp(n->curr->v.h_vector,vector)))
2376 			||(tim==GLOBALS->start_time_vcd_recoder_c_3)
2377 			||(!n->curr->v.h_vector)
2378 			||(GLOBALS->vcd_preserve_glitches)
2379 			) /* same region == go skip */
2380 	        	{
2381 			if(n->curr->time==tim)
2382 				{
2383 				DEBUG(printf("Warning: Glitch at time ["TTFormat"] Signal [%p], Value [%c->%c].\n",
2384 					tim, n, AN_STR[n->curr->v.h_val], ch));
2385 				if(n->curr->v.h_vector) free_2(n->curr->v.h_vector);
2386 				n->curr->v.h_vector=vector;		/* we have a glitch! */
2387 
2388 				GLOBALS->num_glitches_vcd_recoder_c_4++;
2389 				if(!(n->curr->flags&HIST_GLITCH))
2390 					{
2391 					n->curr->flags|=HIST_GLITCH;	/* set the glitch flag */
2392 					GLOBALS->num_glitch_regions_vcd_recoder_c_4++;
2393 					}
2394 				}
2395 				else
2396 				{
2397 	                	he=histent_calloc();
2398 	                	he->time=tim;
2399 	                	he->v.h_vector=vector;
2400 
2401 	                	n->curr->next=he;
2402 				n->curr=he;
2403 	                	GLOBALS->regions+=regadd;
2404 				}
2405 	                }
2406 			else
2407 			{
2408 			free_2(vector);
2409 			}
2410 	       }
2411 	break;
2412 	}
2413 	}
2414 }
2415 
2416 }
2417 
2418 /*******************************************************************************/
2419 
vcd_build_symbols(void)2420 static void vcd_build_symbols(void)
2421 {
2422 int j;
2423 int max_slen=-1;
2424 struct sym_chain *sym_chain=NULL, *sym_curr=NULL;
2425 int duphier=0;
2426 char hashdirty;
2427 struct vcdsymbol *v, *vprime;
2428 char *str = wave_alloca(1); /* quiet scan-build null pointer warning below */
2429 #ifdef _WAVE_HAVE_JUDY
2430 int ss_len, longest = 0;
2431 #endif
2432 
2433 v=GLOBALS->vcdsymroot_vcd_recoder_c_3;
2434 while(v)
2435 	{
2436 	int msi;
2437 	int delta;
2438 
2439 		{
2440 		int slen;
2441 		int substnode;
2442 
2443 		msi=v->msi;
2444 		delta=((v->lsi-v->msi)<0)?-1:1;
2445 		substnode=0;
2446 
2447 		slen=strlen(v->name);
2448 		str=(slen>max_slen)?(wave_alloca((max_slen=slen)+32)):(str); /* more than enough */
2449 		strcpy(str,v->name);
2450 
2451 		if((v->msi>=0)||(v->msi != v->lsi))
2452 			{
2453 			strcpy(str+slen,GLOBALS->vcd_hier_delimeter);
2454 			slen++;
2455 			}
2456 
2457 		if((vprime=bsearch_vcd(v->id, strlen(v->id)))!=v) /* hash mish means dup net */
2458 			{
2459 			if(v->size!=vprime->size)
2460 				{
2461 				fprintf(stderr,"ERROR: Duplicate IDs with differing width: %s %s\n", v->name, vprime->name);
2462 				}
2463 				else
2464 				{
2465 				substnode=1;
2466 				}
2467 			}
2468 
2469 		if((v->size==1)&&(v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE))
2470 			{
2471 			struct symbol *s = NULL;
2472 
2473 			for(j=0;j<v->size;j++)
2474 				{
2475 				if(v->msi>=0)
2476 					{
2477 					if(!GLOBALS->vcd_explicit_zero_subscripts)
2478 						sprintf(str+slen,"%d",msi);
2479 						else
2480 						sprintf(str+slen-1,"[%d]",msi);
2481 					}
2482 
2483 				hashdirty=0;
2484 				if(symfind(str, NULL))
2485 					{
2486 					char *dupfix=(char *)malloc_2(max_slen+32);
2487 #ifndef _WAVE_HAVE_JUDY
2488 					hashdirty=1;
2489 #endif
2490 					DEBUG(fprintf(stderr,"Warning: %s is a duplicate net name.\n",str));
2491 
2492 					do sprintf(dupfix, "$DUP%d%s%s", duphier++, GLOBALS->vcd_hier_delimeter, str);
2493 						while(symfind(dupfix, NULL));
2494 
2495 					strcpy(str, dupfix);
2496 					free_2(dupfix);
2497 					duphier=0; /* reset for next duplicate resolution */
2498 					}
2499 					/* fallthrough */
2500 					{
2501 					s=symadd(str,hashdirty?hash(str):GLOBALS->hashcache);
2502 #ifdef _WAVE_HAVE_JUDY
2503 					ss_len = strlen(str); if(ss_len >= longest) { longest = ss_len + 1; }
2504 #endif
2505 					s->n=v->narray[j];
2506 					if(substnode)
2507 						{
2508 						struct Node *n, *n2;
2509 
2510 						n=s->n;
2511 						n2=vprime->narray[j];
2512 						/* nname stays same */
2513 						/* n->head=n2->head; */
2514 						/* n->curr=n2->curr; */
2515 						n->curr=(hptr)n2;
2516 						/* harray calculated later */
2517 						n->numhist=n2->numhist;
2518 						}
2519 
2520 #ifndef _WAVE_HAVE_JUDY
2521 					s->n->nname=s->name;
2522 #endif
2523 					if(!GLOBALS->firstnode)
2524 					        {
2525 					        GLOBALS->firstnode=
2526 					        GLOBALS->curnode=calloc_2(1, sizeof(struct symchain));
2527 					        }
2528 					        else
2529 					        {
2530 					        GLOBALS->curnode->next=calloc_2(1, sizeof(struct symchain));
2531 					        GLOBALS->curnode=GLOBALS->curnode->next;
2532 					        }
2533 					GLOBALS->curnode->symbol=s;
2534 
2535 					GLOBALS->numfacs++;
2536 					DEBUG(fprintf(stderr,"Added: %s\n",str));
2537 					}
2538 				msi+=delta;
2539 				}
2540 
2541 			if((j==1)&&(v->root))
2542 				{
2543 				s->vec_root=(struct symbol *)v->root;		/* these will get patched over */
2544 				s->vec_chain=(struct symbol *)v->chain;		/* these will get patched over */
2545 				v->sym_chain=s;
2546 
2547 				if(!sym_chain)
2548 					{
2549 					sym_curr=(struct sym_chain *)calloc_2(1,sizeof(struct sym_chain));
2550 					sym_chain=sym_curr;
2551 					}
2552 					else
2553 					{
2554 					sym_curr->next=(struct sym_chain *)calloc_2(1,sizeof(struct sym_chain));
2555 					sym_curr=sym_curr->next;
2556 					}
2557 				sym_curr->val=s;
2558 				}
2559 			}
2560 			else	/* atomic vector */
2561 			{
2562 			if((v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE)&&(v->vartype!=V_INTEGER)&&(v->vartype!=V_PARAMETER))
2563 			/* if((v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE)) */
2564 				{
2565 				sprintf(str+slen-1,"[%d:%d]",v->msi,v->lsi);
2566 				/* 2d add */
2567 				if((v->msi>v->lsi)&&((v->msi-v->lsi+1)!=v->size))
2568 					{
2569 					if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER))
2570 						{
2571 						v->msi = v->size-1; v->lsi = 0;
2572 						}
2573 					}
2574 				else
2575 				if((v->lsi>=v->msi)&&((v->lsi-v->msi+1)!=v->size))
2576 					{
2577 					if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER))
2578 						{
2579 						v->lsi = v->size-1; v->msi = 0;
2580 						}
2581 					}
2582 				}
2583 				else
2584 				{
2585 				*(str+slen-1)=0;
2586 				}
2587 
2588 
2589 			hashdirty=0;
2590 			if(symfind(str, NULL))
2591 				{
2592 				char *dupfix=(char *)malloc_2(max_slen+32);
2593 #ifndef _WAVE_HAVE_JUDY
2594 				hashdirty=1;
2595 #endif
2596 				DEBUG(fprintf(stderr,"Warning: %s is a duplicate net name.\n",str));
2597 
2598 				do sprintf(dupfix, "$DUP%d%s%s", duphier++, GLOBALS->vcd_hier_delimeter, str);
2599 					while(symfind(dupfix, NULL));
2600 
2601 				strcpy(str, dupfix);
2602 				free_2(dupfix);
2603 				duphier=0; /* reset for next duplicate resolution */
2604 				}
2605 				/* fallthrough */
2606 				{
2607 				struct symbol *s;
2608 
2609 				s=symadd(str,hashdirty?hash(str):GLOBALS->hashcache);	/* cut down on double lookups.. */
2610 #ifdef _WAVE_HAVE_JUDY
2611                                 ss_len = strlen(str); if(ss_len >= longest) { longest = ss_len + 1; }
2612 #endif
2613 				s->n=v->narray[0];
2614 				if(substnode)
2615 					{
2616 					struct Node *n, *n2;
2617 
2618 					n=s->n;
2619 					n2=vprime->narray[0];
2620 					/* nname stays same */
2621 					/* n->head=n2->head; */
2622 					/* n->curr=n2->curr; */
2623 					n->curr=(hptr)n2;
2624 					/* harray calculated later */
2625 					n->numhist=n2->numhist;
2626 					n->extvals=n2->extvals;
2627 					n->msi=n2->msi;
2628 					n->lsi=n2->lsi;
2629 					}
2630 					else
2631 					{
2632 					s->n->msi=v->msi;
2633 					s->n->lsi=v->lsi;
2634 
2635 					s->n->extvals=1;
2636 					}
2637 
2638 #ifndef _WAVE_HAVE_JUDY
2639 				s->n->nname=s->name;
2640 #endif
2641 				if(!GLOBALS->firstnode)
2642 				        {
2643 				        GLOBALS->firstnode=
2644 				        GLOBALS->curnode=calloc_2(1, sizeof(struct symchain));
2645 				        }
2646 				        else
2647 				        {
2648 				        GLOBALS->curnode->next=calloc_2(1, sizeof(struct symchain));
2649 				        GLOBALS->curnode=GLOBALS->curnode->next;
2650 				        }
2651 				GLOBALS->curnode->symbol=s;
2652 
2653 				GLOBALS->numfacs++;
2654 				DEBUG(fprintf(stderr,"Added: %s\n",str));
2655 				}
2656 			}
2657 		}
2658 
2659 	v=v->next;
2660 	}
2661 
2662 #ifdef _WAVE_HAVE_JUDY
2663 {
2664 Pvoid_t  PJArray = GLOBALS->sym_judy;
2665 PPvoid_t PPValue;
2666 char *Index = calloc_2(1, longest);
2667 
2668 for (PPValue  = JudySLFirst (PJArray, (uint8_t *)Index, PJE0);
2669          PPValue != (PPvoid_t) NULL;
2670          PPValue  = JudySLNext  (PJArray, (uint8_t *)Index, PJE0))
2671     {
2672 	struct symbol *s = *(struct symbol **)PPValue;
2673 	s->name = strdup_2(Index);
2674 	s->n->nname = s->name;
2675     }
2676 
2677 free_2(Index);
2678 }
2679 #endif
2680 
2681 if(sym_chain)
2682 	{
2683 	sym_curr=sym_chain;
2684 	while(sym_curr)
2685 		{
2686 		sym_curr->val->vec_root= ((struct vcdsymbol *)sym_curr->val->vec_root)->sym_chain;
2687 
2688 		if ((struct vcdsymbol *)sym_curr->val->vec_chain)
2689 			sym_curr->val->vec_chain=((struct vcdsymbol *)sym_curr->val->vec_chain)->sym_chain;
2690 
2691 		DEBUG(printf("Link: ('%s') '%s' -> '%s'\n",sym_curr->val->vec_root->name, sym_curr->val->name, sym_curr->val->vec_chain?sym_curr->val->vec_chain->name:"(END)"));
2692 
2693 		sym_chain=sym_curr;
2694 		sym_curr=sym_curr->next;
2695 		free_2(sym_chain);
2696 		}
2697 	}
2698 }
2699 
2700 /*******************************************************************************/
2701 
vcd_cleanup(void)2702 static void vcd_cleanup(void)
2703 {
2704 struct slist *s, *s2;
2705 struct vcdsymbol *v, *vt;
2706 
2707 if(GLOBALS->indexed_vcd_recoder_c_3)
2708 	{
2709 	free_2(GLOBALS->indexed_vcd_recoder_c_3); GLOBALS->indexed_vcd_recoder_c_3=NULL;
2710 	}
2711 
2712 if(GLOBALS->sorted_vcd_recoder_c_3)
2713 	{
2714 	free_2(GLOBALS->sorted_vcd_recoder_c_3); GLOBALS->sorted_vcd_recoder_c_3=NULL;
2715 	}
2716 
2717 v=GLOBALS->vcdsymroot_vcd_recoder_c_3;
2718 while(v)
2719 	{
2720 	if(v->name) free_2(v->name);
2721 	if(v->id) free_2(v->id);
2722 	if(v->narray) free_2(v->narray);
2723 	vt=v;
2724 	v=v->next;
2725 	free_2(vt);
2726 	}
2727 GLOBALS->vcdsymroot_vcd_recoder_c_3=GLOBALS->vcdsymcurr_vcd_recoder_c_3=NULL;
2728 
2729 if(GLOBALS->slisthier) { free_2(GLOBALS->slisthier); GLOBALS->slisthier=NULL; }
2730 s=GLOBALS->slistroot;
2731 while(s)
2732 	{
2733 	s2=s->next;
2734 	if(s->str)free_2(s->str);
2735 	free_2(s);
2736 	s=s2;
2737 	}
2738 
2739 GLOBALS->slistroot=GLOBALS->slistcurr=NULL; GLOBALS->slisthier_len=0;
2740 
2741 if(GLOBALS->vcd_is_compressed_vcd_recoder_c_2)
2742 	{
2743 	pclose(GLOBALS->vcd_handle_vcd_recoder_c_2);
2744 	GLOBALS->vcd_handle_vcd_recoder_c_2 = NULL;
2745 	}
2746 	else
2747 	{
2748 	fclose(GLOBALS->vcd_handle_vcd_recoder_c_2);
2749 	GLOBALS->vcd_handle_vcd_recoder_c_2 = NULL;
2750 	}
2751 
2752 if(GLOBALS->yytext_vcd_recoder_c_3)
2753 	{
2754 	free_2(GLOBALS->yytext_vcd_recoder_c_3);
2755 	GLOBALS->yytext_vcd_recoder_c_3=NULL;
2756 	}
2757 }
2758 
2759 /*******************************************************************************/
2760 
vcd_recoder_main(char * fname)2761 TimeType vcd_recoder_main(char *fname)
2762 {
2763 unsigned int finalize_cnt = 0;
2764 #ifdef HAVE_SYS_STAT_H
2765 struct stat mystat;
2766 int stat_rc = stat(fname, &mystat);
2767 #endif
2768 
2769 GLOBALS->pv_vcd_recoder_c_3=GLOBALS->rootv_vcd_recoder_c_3=NULL;
2770 GLOBALS->vcd_hier_delimeter[0]=GLOBALS->hier_delimeter;
2771 
2772 if(GLOBALS->use_fastload)
2773 	{
2774         char *ffname = malloc_2(strlen(fname) + 4 + 1);
2775         sprintf(ffname, "%s.idx", fname);
2776 
2777         GLOBALS->vlist_handle = fopen(ffname, "rb");
2778 	if(GLOBALS->vlist_handle)
2779 		{
2780 		GLOBALS->use_fastload = VCD_FSL_READ;
2781 
2782 		/* need to do a sanity check looking for time of vcd file vs recoder file, etc. */
2783 #ifdef HAVE_SYS_STAT_H
2784 		if( (stat_rc) || (!read_fastload_header(&mystat)) )
2785 #else
2786 		if(!read_fastload_header())
2787 #endif
2788 			{
2789 			GLOBALS->use_fastload = VCD_FSL_WRITE;
2790 			fclose(GLOBALS->vlist_handle);
2791 			GLOBALS->vlist_handle = NULL;
2792 			}
2793 		}
2794 		else
2795 		{
2796 		GLOBALS->use_fastload = VCD_FSL_WRITE;
2797 		}
2798 
2799         free_2(ffname);
2800         }
2801 
2802 errno=0;	/* reset in case it's set for some reason */
2803 
2804 GLOBALS->yytext_vcd_recoder_c_3=(char *)malloc_2(GLOBALS->T_MAX_STR_vcd_recoder_c_3+1);
2805 
2806 if(!GLOBALS->hier_was_explicitly_set) /* set default hierarchy split char */
2807 	{
2808 	GLOBALS->hier_delimeter='.';
2809 	}
2810 
2811 if(suffix_check(fname, ".gz") || suffix_check(fname, ".zip"))
2812 	{
2813 	char *str;
2814 	int dlen;
2815 	dlen=strlen(WAVE_DECOMPRESSOR);
2816 	str=wave_alloca(strlen(fname)+dlen+1);
2817 	strcpy(str,WAVE_DECOMPRESSOR);
2818 	strcpy(str+dlen,fname);
2819 	GLOBALS->vcd_handle_vcd_recoder_c_2=popen(str,"r");
2820 	GLOBALS->vcd_is_compressed_vcd_recoder_c_2=~0;
2821 	}
2822 	else
2823 	{
2824 	if(strcmp("-vcd",fname))
2825 		{
2826 		GLOBALS->vcd_handle_vcd_recoder_c_2=fopen(fname,"rb");
2827 
2828 		if(GLOBALS->vcd_handle_vcd_recoder_c_2)
2829 			{
2830 			fseeko(GLOBALS->vcd_handle_vcd_recoder_c_2, 0, SEEK_END);	/* do status bar for vcd load */
2831 			GLOBALS->vcd_fsiz_vcd_recoder_c_2 = ftello(GLOBALS->vcd_handle_vcd_recoder_c_2);
2832 			fseeko(GLOBALS->vcd_handle_vcd_recoder_c_2, 0, SEEK_SET);
2833 			}
2834 
2835 		if(GLOBALS->vcd_warning_filesize < 0) GLOBALS->vcd_warning_filesize = VCD_SIZE_WARN;
2836 
2837 		if(GLOBALS->vcd_warning_filesize)
2838 		if(GLOBALS->vcd_fsiz_vcd_recoder_c_2 > (GLOBALS->vcd_warning_filesize * (1024 * 1024)))
2839 			{
2840 			if(!GLOBALS->vlist_prepack)
2841 				{
2842 				fprintf(stderr, "Warning! File size is %d MB.  This might fail in recoding.\n"
2843 					"Consider converting it to the FST database format instead.  (See the\n"
2844 					"vcd2fst(1) manpage for more information.)\n"
2845 					"To disable this warning, set rc variable vcd_warning_filesize to zero.\n"
2846 					"Alternatively, use the -o, --optimize command line option to convert to FST\n"
2847 					"or the -g, --giga command line option to use dynamically compressed memory.\n\n",
2848 						(int)(GLOBALS->vcd_fsiz_vcd_recoder_c_2/(1024*1024)));
2849 				}
2850 				else
2851 				{
2852 				fprintf(stderr, "VCDLOAD | File size is %d MB, using vlist prepacking%s.\n\n",
2853 						(int)(GLOBALS->vcd_fsiz_vcd_recoder_c_2/(1024*1024)),
2854 						GLOBALS->vlist_spill_to_disk ? " and spill file" : "");
2855 				}
2856 			}
2857 		}
2858 		else
2859 		{
2860 		GLOBALS->splash_disable = 1;
2861 		GLOBALS->vcd_handle_vcd_recoder_c_2=stdin;
2862 		}
2863 	GLOBALS->vcd_is_compressed_vcd_recoder_c_2=0;
2864 	}
2865 
2866 if(!GLOBALS->vcd_handle_vcd_recoder_c_2)
2867 	{
2868 	fprintf(stderr, "Error opening %s .vcd file '%s'.\n",
2869 		GLOBALS->vcd_is_compressed_vcd_recoder_c_2?"compressed":"", fname);
2870 	perror("Why");
2871 	vcd_exit(255);
2872 	}
2873 
2874 /* SPLASH */				splash_create();
2875 
2876 sym_hash_initialize(GLOBALS);
2877 getch_alloc();		/* alloc membuff for vcd getch buffer */
2878 
2879 build_slisthier();
2880 
2881 GLOBALS->time_vlist_vcd_recoder_c_1 = vlist_create(sizeof(TimeType));
2882 
2883 if(GLOBALS->use_fastload == VCD_FSL_WRITE)
2884 	{
2885 	GLOBALS->time_vlist_vcd_recoder_write = ((struct vlist_t *)vlist_packer_create());
2886 	}
2887 
2888 if((GLOBALS->vlist_spill_to_disk) && (GLOBALS->use_fastload != VCD_FSL_READ))
2889 	{
2890 	vlist_init_spillfile();
2891 	}
2892 
2893 vcd_parse();
2894 if(GLOBALS->varsplit_vcd_recoder_c_3)
2895 	{
2896         free_2(GLOBALS->varsplit_vcd_recoder_c_3);
2897         GLOBALS->varsplit_vcd_recoder_c_3=NULL;
2898         }
2899 
2900 if(GLOBALS->vlist_handle)
2901 	{
2902 	FILE *vh = GLOBALS->vlist_handle;
2903 	GLOBALS->vlist_handle = NULL;
2904 	vlist_freeze(&GLOBALS->time_vlist_vcd_recoder_c_1);
2905 	GLOBALS->vlist_handle = vh;
2906 	}
2907 	else
2908 	{
2909 	vlist_freeze(&GLOBALS->time_vlist_vcd_recoder_c_1);
2910 	}
2911 
2912 if(GLOBALS->time_vlist_vcd_recoder_write)
2913 	{
2914 	write_fastload_time_section();
2915 	}
2916 
2917 if(GLOBALS->use_fastload != VCD_FSL_READ)
2918 	{
2919 	finalize_cnt = vlist_emit_finalize();
2920 	}
2921 
2922 if(GLOBALS->time_vlist_vcd_recoder_write)
2923 	{
2924 #ifdef HAVE_SYS_STAT_H
2925 	write_fastload_header(&mystat, finalize_cnt);
2926 #else
2927 	write_fastload_header(finalize_cnt);
2928 #endif
2929 	}
2930 
2931 
2932 if((!GLOBALS->sorted_vcd_recoder_c_3)&&(!GLOBALS->indexed_vcd_recoder_c_3))
2933 	{
2934 	fprintf(stderr, "No symbols in VCD file..is it malformed?  Exiting!\n");
2935 	vcd_exit(255);
2936 	}
2937 
2938 if(GLOBALS->vcd_save_handle) { fclose(GLOBALS->vcd_save_handle); GLOBALS->vcd_save_handle = NULL; }
2939 
2940 fprintf(stderr, "["TTFormat"] start time.\n["TTFormat"] end time.\n", GLOBALS->start_time_vcd_recoder_c_3*GLOBALS->time_scale, GLOBALS->end_time_vcd_recoder_c_3*GLOBALS->time_scale);
2941 
2942 if(GLOBALS->vcd_fsiz_vcd_recoder_c_2)
2943         {
2944         splash_sync(GLOBALS->vcd_fsiz_vcd_recoder_c_2, GLOBALS->vcd_fsiz_vcd_recoder_c_2);
2945 	GLOBALS->vcd_fsiz_vcd_recoder_c_2 = 0;
2946         }
2947 else
2948 if(GLOBALS->vcd_is_compressed_vcd_recoder_c_2)
2949 	{
2950         splash_sync(1,1);
2951 	GLOBALS->vcd_fsiz_vcd_recoder_c_2 = 0;
2952 	}
2953 
2954 GLOBALS->min_time=GLOBALS->start_time_vcd_recoder_c_3*GLOBALS->time_scale;
2955 GLOBALS->max_time=GLOBALS->end_time_vcd_recoder_c_3*GLOBALS->time_scale;
2956 GLOBALS->global_time_offset = GLOBALS->global_time_offset * GLOBALS->time_scale;
2957 
2958 if((GLOBALS->min_time==GLOBALS->max_time)&&(GLOBALS->max_time==LLDescriptor(-1)))
2959         {
2960         fprintf(stderr, "VCD times range is equal to zero.  Exiting.\n");
2961         vcd_exit(255);
2962         }
2963 
2964 vcd_build_symbols();
2965 vcd_sortfacs();
2966 vcd_cleanup();
2967 
2968 getch_free();		/* free membuff for vcd getch buffer */
2969 
2970 
2971 if(GLOBALS->blackout_regions)
2972 	{
2973 	struct blackout_region_t *bt = GLOBALS->blackout_regions;
2974 	while(bt)
2975 		{
2976 		bt->bstart *= GLOBALS->time_scale;
2977 		bt->bend *= GLOBALS->time_scale;
2978 		bt = bt->next;
2979 		}
2980 	}
2981 
2982 /* is_vcd=~0; */
2983 GLOBALS->is_lx2 = LXT2_IS_VLIST;
2984 
2985 /* SPLASH */                            splash_finalize();
2986 return(GLOBALS->max_time);
2987 }
2988 
2989 /*******************************************************************************/
2990 
vcd_import_masked(void)2991 void vcd_import_masked(void)
2992 {
2993 /* nothing */
2994 }
2995 
vcd_set_fac_process_mask(nptr np)2996 void vcd_set_fac_process_mask(nptr np)
2997 {
2998 if(np && np->mv.mvlfac_vlist)
2999 	{
3000 	import_vcd_trace(np);
3001 	}
3002 }
3003 
3004 
3005 #define vlist_locate_import(x,y) ((GLOBALS->vlist_prepack) ? ((depacked) + (y)) : vlist_locate((x),(y)))
3006 
import_vcd_trace(nptr np)3007 void import_vcd_trace(nptr np)
3008 {
3009 struct vlist_t *v = np->mv.mvlfac_vlist;
3010 int len = 1;
3011 unsigned int list_size;
3012 unsigned char vlist_type;
3013 /* unsigned int vartype = 0; */ /* scan-build */
3014 unsigned int vlist_pos = 0;
3015 unsigned char *chp;
3016 unsigned int time_idx = 0;
3017 TimeType *curtime_pnt;
3018 unsigned char arr[5];
3019 int arr_pos;
3020 unsigned int accum;
3021 unsigned char ch;
3022 double *d;
3023 unsigned char *depacked = NULL;
3024 
3025 if(!v) return;
3026 vlist_uncompress(&v);
3027 
3028 if(GLOBALS->vlist_prepack)
3029 	{
3030 	depacked = vlist_packer_decompress(v, &list_size);
3031 	vlist_destroy(v);
3032 	}
3033 	else
3034 	{
3035 	list_size=vlist_size(v);
3036 	}
3037 
3038 if(!list_size)
3039 	{
3040 	len = 1;
3041 	vlist_type = '!'; /* possible alias */
3042 	}
3043 	else
3044 	{
3045 	chp = vlist_locate_import(v, vlist_pos++);
3046 	if(chp)
3047 		{
3048 		switch((vlist_type = (*chp & 0x7f)))
3049 			{
3050 			case '0':
3051 				len = 1;
3052 				chp = vlist_locate_import(v, vlist_pos++);
3053 				if(!chp)
3054 					{
3055 					fprintf(stderr, "Internal error file '%s' line %d, exiting.\n", __FILE__, __LINE__);
3056 					exit(255);
3057 					}
3058 				/* vartype = (unsigned int)(*chp & 0x7f); */ /*scan-build */
3059 				break;
3060 
3061 			case 'B':
3062 			case 'R':
3063 			case 'S':
3064 				chp = vlist_locate_import(v, vlist_pos++);
3065 				if(!chp)
3066 					{
3067 					fprintf(stderr, "Internal error file '%s' line %d, exiting.\n", __FILE__, __LINE__);
3068 					exit(255);
3069 					}
3070 				/* vartype = (unsigned int)(*chp & 0x7f); */ /* scan-build */
3071 
3072 				arr_pos = accum = 0;
3073 
3074 		                do      {
3075 		                	chp = vlist_locate_import(v, vlist_pos++);
3076 		                        if(!chp) break;
3077 		                        ch = *chp;
3078 					arr[arr_pos++] = ch;
3079 		                        } while (!(ch & 0x80));
3080 
3081 				for(--arr_pos; arr_pos>=0; arr_pos--)
3082 					{
3083 					ch = arr[arr_pos];
3084 					accum <<= 7;
3085 					accum |= (unsigned int)(ch & 0x7f);
3086 					}
3087 
3088 				len = accum;
3089 
3090 				break;
3091 
3092 			default:
3093 				fprintf(stderr, "Unsupported vlist type '%c', exiting.", vlist_type);
3094 				vcd_exit(255);
3095 				break;
3096 			}
3097 		}
3098 		else
3099 		{
3100 		len = 1;
3101 		vlist_type = '!'; /* possible alias */
3102 		}
3103 	}
3104 
3105 
3106 if(vlist_type == '0') /* single bit */
3107 	{
3108 	while(vlist_pos < list_size)
3109 		{
3110 		unsigned int delta, bitval;
3111 		char ascval;
3112 
3113 		arr_pos = accum = 0;
3114 
3115                 do      {
3116                 	chp = vlist_locate_import(v, vlist_pos++);
3117                         if(!chp) break;
3118                         ch = *chp;
3119 			arr[arr_pos++] = ch;
3120                         } while (!(ch & 0x80));
3121 
3122 		for(--arr_pos; arr_pos>=0; arr_pos--)
3123 			{
3124 			ch = arr[arr_pos];
3125 			accum <<= 7;
3126 			accum |= (unsigned int)(ch & 0x7f);
3127 			}
3128 
3129 		if(!(accum&1))
3130 			{
3131 			delta = accum >> 2;
3132 			bitval = (accum >> 1) & 1;
3133 			ascval = '0' + bitval;
3134 			}
3135 			else
3136 			{
3137 			delta = accum >> 4;
3138 			bitval = (accum >> 1) & 7;
3139 			ascval = RCV_STR[bitval];
3140 			}
3141 		time_idx += delta;
3142 
3143 		curtime_pnt = vlist_locate(GLOBALS->time_vlist_vcd_recoder_c_1, time_idx ? time_idx-1 : 0);
3144 		if(!curtime_pnt)
3145 			{
3146 			fprintf(stderr, "GTKWAVE | malformed bitwise signal data for '%s' after time_idx = %d\n",
3147 				np->nname, time_idx - delta);
3148 			exit(255);
3149 			}
3150 
3151 		add_histent(*curtime_pnt,np,ascval,1, NULL);
3152 		}
3153 
3154 	add_histent(MAX_HISTENT_TIME-1, np, 'x', 0, NULL);
3155 	add_histent(MAX_HISTENT_TIME,   np, 'z', 0, NULL);
3156 	}
3157 else if(vlist_type == 'B') /* bit vector, port type was converted to bit vector already */
3158 	{
3159 	char *sbuf = malloc_2(len+1);
3160 	int dst_len;
3161 	char *vector;
3162 
3163 	while(vlist_pos < list_size)
3164 		{
3165 		unsigned int delta;
3166 
3167 		arr_pos = accum = 0;
3168 
3169                 do      {
3170                 	chp = vlist_locate_import(v, vlist_pos++);
3171                         if(!chp) break;
3172                         ch = *chp;
3173 			arr[arr_pos++] = ch;
3174                         } while (!(ch & 0x80));
3175 
3176 		for(--arr_pos; arr_pos>=0; arr_pos--)
3177 			{
3178 			ch = arr[arr_pos];
3179 			accum <<= 7;
3180 			accum |= (unsigned int)(ch & 0x7f);
3181 			}
3182 
3183 		delta = accum;
3184 		time_idx += delta;
3185 
3186 		curtime_pnt = vlist_locate(GLOBALS->time_vlist_vcd_recoder_c_1,  time_idx ? time_idx-1 : 0);
3187 		if(!curtime_pnt)
3188 			{
3189 			fprintf(stderr, "GTKWAVE | malformed 'b' signal data for '%s' after time_idx = %d\n",
3190 				np->nname, time_idx - delta);
3191 			exit(255);
3192 			}
3193 
3194 		dst_len = 0;
3195 		for(;;)
3196 			{
3197 			chp = vlist_locate_import(v, vlist_pos++);
3198 			if(!chp) break;
3199 			ch = *chp;
3200 			if((ch >> 4) == AN_MSK) break;
3201 			if(dst_len == len) { if(len != 1) memmove(sbuf, sbuf+1, dst_len - 1); dst_len--; }
3202 			sbuf[dst_len++] = AN_STR[ch >> 4];
3203 			if((ch & AN_MSK) == AN_MSK) break;
3204 			if(dst_len == len) { if(len != 1) memmove(sbuf, sbuf+1, dst_len - 1); dst_len--; }
3205 			sbuf[dst_len++] = AN_STR[ch & AN_MSK];
3206 			}
3207 
3208 		if(len == 1)
3209 			{
3210 			add_histent(*curtime_pnt, np,sbuf[0],1, NULL);
3211 			}
3212 			else
3213 			{
3214 			vector = malloc_2(len+1);
3215 			if(dst_len < len)
3216 				{
3217 				unsigned char extend=(sbuf[0]=='1')?'0':sbuf[0];
3218 				memset(vector, extend, len - dst_len);
3219 				memcpy(vector + (len - dst_len), sbuf, dst_len);
3220 				}
3221 				else
3222 				{
3223 				memcpy(vector, sbuf, len);
3224 				}
3225 
3226 			vector[len] = 0;
3227 			add_histent(*curtime_pnt, np,0,1,vector);
3228 			}
3229 		}
3230 
3231 	if(len==1)
3232 		{
3233 		add_histent(MAX_HISTENT_TIME-1, np, 'x', 0, NULL);
3234 		add_histent(MAX_HISTENT_TIME,   np, 'z', 0, NULL);
3235 		}
3236 		else
3237 		{
3238 		add_histent(MAX_HISTENT_TIME-1, np, 'x', 0, (char *)calloc_2(1,sizeof(char)));
3239 		add_histent(MAX_HISTENT_TIME,   np, 'z', 0, (char *)calloc_2(1,sizeof(char)));
3240 		}
3241 
3242 	free_2(sbuf);
3243 	}
3244 else if(vlist_type == 'R') /* real */
3245 	{
3246 	char *sbuf = malloc_2(64);
3247 	int dst_len;
3248 	char *vector;
3249 
3250 	while(vlist_pos < list_size)
3251 		{
3252 		unsigned int delta;
3253 
3254 		arr_pos = accum = 0;
3255 
3256                 do      {
3257                 	chp = vlist_locate_import(v, vlist_pos++);
3258                         if(!chp) break;
3259                         ch = *chp;
3260 			arr[arr_pos++] = ch;
3261                         } while (!(ch & 0x80));
3262 
3263 		for(--arr_pos; arr_pos>=0; arr_pos--)
3264 			{
3265 			ch = arr[arr_pos];
3266 			accum <<= 7;
3267 			accum |= (unsigned int)(ch & 0x7f);
3268 			}
3269 
3270 		delta = accum;
3271 		time_idx += delta;
3272 
3273 		curtime_pnt = vlist_locate(GLOBALS->time_vlist_vcd_recoder_c_1,  time_idx ? time_idx-1 : 0);
3274 		if(!curtime_pnt)
3275 			{
3276 			fprintf(stderr, "GTKWAVE | malformed 'r' signal data for '%s' after time_idx = %d\n",
3277 				np->nname, time_idx - delta);
3278 			exit(255);
3279 			}
3280 
3281 		dst_len = 0;
3282 		do
3283 			{
3284 			chp = vlist_locate_import(v, vlist_pos++);
3285 			if(!chp) break;
3286 			ch = *chp;
3287 			sbuf[dst_len++] = ch;
3288 			} while(ch);
3289 
3290 		vector=malloc_2(sizeof(double));
3291 		sscanf(sbuf,"%lg",(double *)vector);
3292 		add_histent(*curtime_pnt, np,'g',1,(char *)vector);
3293 		}
3294 
3295 	d=malloc_2(sizeof(double));
3296 	*d=1.0;
3297 	add_histent(MAX_HISTENT_TIME-1, np, 'g', 0, (char *)d);
3298 
3299 	d=malloc_2(sizeof(double));
3300 	*d=0.0;
3301 	add_histent(MAX_HISTENT_TIME, np, 'g', 0, (char *)d);
3302 
3303 	free_2(sbuf);
3304 	}
3305 else if(vlist_type == 'S') /* string */
3306 	{
3307 	char *sbuf = malloc_2(list_size); /* being conservative */
3308 	int dst_len;
3309 	char *vector;
3310 
3311 	while(vlist_pos < list_size)
3312 		{
3313 		unsigned int delta;
3314 
3315 		arr_pos = accum = 0;
3316 
3317                 do      {
3318                 	chp = vlist_locate_import(v, vlist_pos++);
3319                         if(!chp) break;
3320                         ch = *chp;
3321 			arr[arr_pos++] = ch;
3322                         } while (!(ch & 0x80));
3323 
3324 		for(--arr_pos; arr_pos>=0; arr_pos--)
3325 			{
3326 			ch = arr[arr_pos];
3327 			accum <<= 7;
3328 			accum |= (unsigned int)(ch & 0x7f);
3329 			}
3330 
3331 		delta = accum;
3332 		time_idx += delta;
3333 
3334 		curtime_pnt = vlist_locate(GLOBALS->time_vlist_vcd_recoder_c_1,  time_idx ? time_idx-1 : 0);
3335 		if(!curtime_pnt)
3336 			{
3337 			fprintf(stderr, "GTKWAVE | malformed 's' signal data for '%s' after time_idx = %d\n",
3338 				np->nname, time_idx - delta);
3339 			exit(255);
3340 			}
3341 
3342 		dst_len = 0;
3343 		do
3344 			{
3345 			chp = vlist_locate_import(v, vlist_pos++);
3346 			if(!chp) break;
3347 			ch = *chp;
3348 			sbuf[dst_len++] = ch;
3349 			} while(ch);
3350 
3351 		vector=malloc_2(dst_len + 1);
3352 		strcpy(vector, sbuf);
3353 		add_histent(*curtime_pnt, np,'s',1,(char *)vector);
3354 		}
3355 
3356 	d=malloc_2(sizeof(double));
3357 	*d=1.0;
3358 	add_histent(MAX_HISTENT_TIME-1, np, 'g', 0, (char *)d);
3359 
3360 	d=malloc_2(sizeof(double));
3361 	*d=0.0;
3362 	add_histent(MAX_HISTENT_TIME, np, 'g', 0, (char *)d);
3363 
3364 	free_2(sbuf);
3365 	}
3366 else if(vlist_type == '!') /* error in loading */
3367 	{
3368 	nptr n2 = (nptr)np->curr;
3369 
3370 	if((n2)&&(n2 != np))	/* keep out any possible infinite recursion from corrupt pointer bugs */
3371 		{
3372 		import_vcd_trace(n2);
3373 
3374 		if(GLOBALS->vlist_prepack)
3375 			{
3376 			vlist_packer_decompress_destroy((char *)depacked);
3377 			}
3378 			else
3379 			{
3380 			vlist_destroy(v);
3381 			}
3382 		np->mv.mvlfac_vlist = NULL;
3383 
3384 		np->head = n2->head;
3385 		np->curr = n2->curr;
3386 		return;
3387 		}
3388 
3389 	fprintf(stderr, "Error in decompressing vlist for '%s', exiting.\n", np->nname);
3390 	vcd_exit(255);
3391 	}
3392 
3393 if(GLOBALS->vlist_prepack)
3394 	{
3395 	vlist_packer_decompress_destroy((char *)depacked);
3396 	}
3397 	else
3398 	{
3399 	vlist_destroy(v);
3400 	}
3401 np->mv.mvlfac_vlist = NULL;
3402 }
3403 
3404