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 partial loader support 04aug06ajb
27  * added real_parameter vartype 04aug06ajb
28  * added in/out port vartype	31jan07ajb
29  * use gperf for port vartypes  19feb07ajb
30  * MTI SV implicit-var fix      05apr07ajb
31  * MTI SV len=0 is real var     05apr07ajb
32  */
33 #include <config.h>
34 #include "globals.h"
35 #include "vcd.h"
36 #include "hierpack.h"
37 
38 #if !defined _MSC_VER && !defined __MINGW32__
39 #include <sys/time.h>
40 #include <sys/types.h>
41 #include <unistd.h>
42 #endif
43 
44 #ifdef __MINGW32__
45 #include <windows.h>
46 #endif
47 
48 #undef VCD_BSEARCH_IS_PERFECT		/* bsearch is imperfect under linux, but OK under AIX */
49 
50 static hptr add_histent_p(TimeType time, struct Node *n, char ch, int regadd, char *vector);
51 static void add_tail_histents(void);
52 static void vcd_build_symbols(void);
53 static void vcd_cleanup(void);
54 static void evcd_strcpy(char *dst, char *src);
55 
56 
57 
58 
59 
60 /*******************************************************************************/
61 
62 #define WAVE_PARTIAL_VCD_RING_BUFFER_SIZE (1024*1024)
63 
64 
get_8(char * p)65 unsigned int get_8(char *p)
66 {
67 if(p >= (GLOBALS->buf_vcd_partial_c_2 + WAVE_PARTIAL_VCD_RING_BUFFER_SIZE))
68         {
69         p-= WAVE_PARTIAL_VCD_RING_BUFFER_SIZE;
70         }
71 
72 return((unsigned int)((unsigned char)*p));
73 }
74 
get_32(char * p)75 unsigned int get_32(char *p)
76 {
77 unsigned int rc;
78 rc =    (get_8(p++) << 24) ;
79 rc|=    (get_8(p++) << 16) ;
80 rc|=    (get_8(p++) <<  8) ;
81 rc|=    (get_8(p)   <<  0) ;
82 
83 return(rc);
84 }
85 
86 
consume(void)87 int consume(void)       /* for testing only */
88 {
89 int len;
90 
91 GLOBALS->consume_countdown_vcd_partial_c_1--;
92 if(!GLOBALS->consume_countdown_vcd_partial_c_1)
93 	{
94 	GLOBALS->consume_countdown_vcd_partial_c_1 = 100000;
95 	return(0);
96 	}
97 
98 if((len = *GLOBALS->consume_ptr_vcd_partial_c_1))
99         {
100         int i;
101 
102         len = get_32(GLOBALS->consume_ptr_vcd_partial_c_1+1);
103         for(i=0;i<len;i++)
104                 {
105                 GLOBALS->vcdbuf_vcd_partial_c_2[i] = get_8(GLOBALS->consume_ptr_vcd_partial_c_1+i+5);
106                 }
107         GLOBALS->vcdbuf_vcd_partial_c_2[i] = 0;
108 
109         *GLOBALS->consume_ptr_vcd_partial_c_1 = 0;
110         GLOBALS->consume_ptr_vcd_partial_c_1 = GLOBALS->consume_ptr_vcd_partial_c_1+i+5;
111         if(GLOBALS->consume_ptr_vcd_partial_c_1 >= (GLOBALS->buf_vcd_partial_c_2 + WAVE_PARTIAL_VCD_RING_BUFFER_SIZE))
112                 {
113                 GLOBALS->consume_ptr_vcd_partial_c_1 -= WAVE_PARTIAL_VCD_RING_BUFFER_SIZE;
114                 }
115         }
116 
117 return(len);
118 }
119 
120 
121 /******************************************************************/
122 
123 enum Tokens   { T_VAR, T_END, T_SCOPE, T_UPSCOPE,
124 		T_COMMENT, T_DATE, T_DUMPALL, T_DUMPOFF, T_DUMPON,
125 		T_DUMPVARS, T_ENDDEFINITIONS,
126 		T_DUMPPORTS, T_DUMPPORTSOFF, T_DUMPPORTSON, T_DUMPPORTSALL,
127 		T_TIMESCALE, T_VERSION, T_VCDCLOSE, T_TIMEZERO,
128 		T_EOF, T_STRING, T_UNKNOWN_KEY };
129 
130 static char *tokens[]={ "var", "end", "scope", "upscope",
131                  "comment", "date", "dumpall", "dumpoff", "dumpon",
132                  "dumpvars", "enddefinitions",
133                  "dumpports", "dumpportsoff", "dumpportson", "dumpportsall",
134                  "timescale", "version", "vcdclose", "timezero",
135                  "", "", "" };
136 
137 
138 #define NUM_TOKENS 19
139 
140 
141 #define T_GET tok=get_token();if((tok==T_END)||(tok==T_EOF))break;
142 
143 /******************************************************************/
144 
145 #define NUM_VTOKENS 23
146 
147 /******************************************************************/
148 
149 
vcdid_hash(char * s,int len)150 static unsigned int vcdid_hash(char *s, int len)
151 {
152 unsigned int val=0;
153 int i;
154 
155 s+=(len-1);
156 
157 for(i=0;i<len;i++)
158         {
159         val *= 94;
160         val += (((unsigned char)*s) - 32);
161         s--;
162         }
163 
164 return(val);
165 }
166 
167 /******************************************************************/
168 
169 /*
170  * bsearch compare
171  */
vcdsymbsearchcompare(const void * s1,const void * s2)172 static int vcdsymbsearchcompare(const void *s1, const void *s2)
173 {
174 char *v1;
175 struct vcdsymbol *v2;
176 
177 v1=(char *)s1;
178 v2=*((struct vcdsymbol **)s2);
179 
180 return(strcmp(v1, v2->id));
181 }
182 
183 
184 /*
185  * actual bsearch
186  */
bsearch_vcd(char * key,int len)187 static struct vcdsymbol *bsearch_vcd(char *key, int len)
188 {
189 struct vcdsymbol **v;
190 struct vcdsymbol *t;
191 
192 if(GLOBALS->indexed_vcd_partial_c_2)
193         {
194         unsigned int hsh = vcdid_hash(key, len);
195         if((hsh>=GLOBALS->vcd_minid_vcd_partial_c_2)&&(hsh<=GLOBALS->vcd_maxid_vcd_partial_c_2))
196                 {
197                 return(GLOBALS->indexed_vcd_partial_c_2[hsh-GLOBALS->vcd_minid_vcd_partial_c_2]);
198                 }
199 
200 	return(NULL);
201         }
202 
203 if(GLOBALS->sorted_vcd_partial_c_2)
204 	{
205 	v=(struct vcdsymbol **)bsearch(key, GLOBALS->sorted_vcd_partial_c_2, GLOBALS->numsyms_vcd_partial_c_2,
206 		sizeof(struct vcdsymbol *), vcdsymbsearchcompare);
207 
208 	if(v)
209 		{
210 		#ifndef VCD_BSEARCH_IS_PERFECT
211 			for(;;)
212 				{
213 				t=*v;
214 
215 				if((v==GLOBALS->sorted_vcd_partial_c_2)||(strcmp((*(--v))->id, key)))
216 					{
217 					return(t);
218 					}
219 				}
220 		#else
221 			return(*v);
222 		#endif
223 		}
224 		else
225 		{
226 		return(NULL);
227 		}
228 	}
229 	else
230 	{
231 	if(!GLOBALS->err_vcd_partial_c_2)
232 		{
233 		fprintf(stderr, "Near byte %d, VCD search table NULL..is this a VCD file?\n", (int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)));
234 		GLOBALS->err_vcd_partial_c_2=1;
235 		}
236 	return(NULL);
237 	}
238 }
239 
240 
241 /*
242  * sort on vcdsymbol pointers
243  */
vcdsymcompare(const void * s1,const void * s2)244 static int vcdsymcompare(const void *s1, const void *s2)
245 {
246 struct vcdsymbol *v1, *v2;
247 
248 v1=*((struct vcdsymbol **)s1);
249 v2=*((struct vcdsymbol **)s2);
250 
251 return(strcmp(v1->id, v2->id));
252 }
253 
254 
255 /*
256  * create sorted (by id) table
257  */
create_sorted_table(void)258 static void create_sorted_table(void)
259 {
260 struct vcdsymbol *v;
261 struct vcdsymbol **pnt;
262 unsigned int vcd_distance;
263 
264 if(GLOBALS->sorted_vcd_partial_c_2)
265 	{
266 	free_2(GLOBALS->sorted_vcd_partial_c_2);	/* this means we saw a 2nd enddefinition chunk! */
267 	GLOBALS->sorted_vcd_partial_c_2=NULL;
268 	}
269 
270 if(GLOBALS->indexed_vcd_partial_c_2)
271 	{
272 	free_2(GLOBALS->indexed_vcd_partial_c_2);
273 	GLOBALS->indexed_vcd_partial_c_2=NULL;
274 	}
275 
276 if(GLOBALS->numsyms_vcd_partial_c_2)
277 	{
278         vcd_distance = GLOBALS->vcd_maxid_vcd_partial_c_2 - GLOBALS->vcd_minid_vcd_partial_c_2 + 1;
279 
280         if((vcd_distance <= VCD_INDEXSIZ)||(!GLOBALS->vcd_hash_kill))
281                 {
282                 GLOBALS->indexed_vcd_partial_c_2 = (struct vcdsymbol **)calloc_2(vcd_distance, sizeof(struct vcdsymbol *));
283 
284 		/* printf("%d symbols span ID range of %d, using indexing...\n", numsyms, vcd_distance); */
285 
286                 v=GLOBALS->vcdsymroot_vcd_partial_c_2;
287                 while(v)
288                         {
289                         if(!GLOBALS->indexed_vcd_partial_c_2[v->nid - GLOBALS->vcd_minid_vcd_partial_c_2]) GLOBALS->indexed_vcd_partial_c_2[v->nid - GLOBALS->vcd_minid_vcd_partial_c_2] = v;
290                         v=v->next;
291                         }
292                 }
293                 else
294 		{
295 		pnt=GLOBALS->sorted_vcd_partial_c_2=(struct vcdsymbol **)calloc_2(GLOBALS->numsyms_vcd_partial_c_2, sizeof(struct vcdsymbol *));
296 		v=GLOBALS->vcdsymroot_vcd_partial_c_2;
297 		while(v)
298 			{
299 			*(pnt++)=v;
300 			v=v->next;
301 			}
302 
303 		qsort(GLOBALS->sorted_vcd_partial_c_2, GLOBALS->numsyms_vcd_partial_c_2, sizeof(struct vcdsymbol *), vcdsymcompare);
304 		}
305 	}
306 }
307 
308 /******************************************************************/
309 
310 /*
311  * single char get inlined/optimized
312  */
getch_alloc(void)313 static void getch_alloc(void)
314 {
315 GLOBALS->vend_vcd_partial_c_2=GLOBALS->vst_vcd_partial_c_2=GLOBALS->vcdbuf_vcd_partial_c_2=(char *)calloc_2(1,VCD_BSIZ);
316 }
317 
318 
getch_fetch(void)319 static int getch_fetch(void)
320 {
321 size_t rd;
322 
323 errno = 0;
324 
325 GLOBALS->vcdbyteno_vcd_partial_c_2+=(GLOBALS->vend_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2);
326 rd=consume();
327 GLOBALS->vend_vcd_partial_c_2=(GLOBALS->vst_vcd_partial_c_2=GLOBALS->vcdbuf_vcd_partial_c_2)+rd;
328 
329 if(!rd) return(-1);
330 
331 return((int)(*GLOBALS->vst_vcd_partial_c_2));
332 }
333 
getch(void)334 static inline signed char getch(void) {
335   signed char ch = ((GLOBALS->vst_vcd_partial_c_2!=GLOBALS->vend_vcd_partial_c_2)?((int)(*GLOBALS->vst_vcd_partial_c_2)):(getch_fetch()));
336   if(ch>=0) { GLOBALS->vst_vcd_partial_c_2++; };
337   return(ch);
338 }
339 
getch_peek(void)340 static inline signed char getch_peek(void) {
341   signed char ch = ((GLOBALS->vst_vcd_partial_c_2!=GLOBALS->vend_vcd_partial_c_2)?((int)(*GLOBALS->vst_vcd_partial_c_2)):(getch_fetch()));
342   /* no increment */
343   return(ch);
344 }
345 
346 
getch_patched(void)347 static int getch_patched(void)
348 {
349 char ch;
350 
351 ch=*GLOBALS->vsplitcurr_vcd_partial_c_2;
352 if(!ch)
353 	{
354 	return(-1);
355 	}
356 	else
357 	{
358 	GLOBALS->vsplitcurr_vcd_partial_c_2++;
359 	return((int)ch);
360 	}
361 }
362 
363 /*
364  * simple tokenizer
365  */
get_token(void)366 static int get_token(void)
367 {
368 int ch;
369 int i, len=0;
370 int is_string=0;
371 char *yyshadow;
372 
373 for(;;)
374 	{
375 	ch=getch();
376 	if(ch<0) return(T_EOF);
377 	if(ch<=' ') continue;	/* val<=' ' is a quick whitespace check      */
378 	break;			/* (take advantage of fact that vcd is text) */
379 	}
380 if(ch=='$')
381 	{
382 	GLOBALS->yytext_vcd_partial_c_2[len++]=ch;
383 	for(;;)
384 		{
385 		ch=getch();
386 		if(ch<0) return(T_EOF);
387 		if(ch<=' ') continue;
388 		break;
389 		}
390 	}
391 	else
392 	{
393 	is_string=1;
394 	}
395 
396 for(GLOBALS->yytext_vcd_partial_c_2[len++]=ch;;GLOBALS->yytext_vcd_partial_c_2[len++]=ch)
397 	{
398 	if(len==GLOBALS->T_MAX_STR_vcd_partial_c_2)
399 		{
400 		GLOBALS->yytext_vcd_partial_c_2=(char *)realloc_2(GLOBALS->yytext_vcd_partial_c_2, (GLOBALS->T_MAX_STR_vcd_partial_c_2=GLOBALS->T_MAX_STR_vcd_partial_c_2*2)+1);
401 		}
402 	ch=getch();
403 	if(ch<=' ') break;
404 	}
405 GLOBALS->yytext_vcd_partial_c_2[len]=0;	/* terminator */
406 
407 if(is_string)
408 	{
409 	GLOBALS->yylen_vcd_partial_c_2=len;
410 	return(T_STRING);
411 	}
412 
413 yyshadow=GLOBALS->yytext_vcd_partial_c_2;
414 do
415 {
416 yyshadow++;
417 for(i=0;i<NUM_TOKENS;i++)
418 	{
419 	if(!strcmp(yyshadow,tokens[i]))
420 		{
421 		return(i);
422 		}
423 	}
424 
425 } while(*yyshadow=='$'); /* fix for RCS ids in version strings */
426 
427 return(T_UNKNOWN_KEY);
428 }
429 
430 
get_vartoken_patched(int match_kw)431 static int get_vartoken_patched(int match_kw)
432 {
433 int ch;
434 int len=0;
435 
436 if(!GLOBALS->var_prevch_vcd_partial_c_2)
437 	{
438 	for(;;)
439 		{
440 		ch=getch_patched();
441 		if(ch<0) { free_2(GLOBALS->varsplit_vcd_partial_c_2); GLOBALS->varsplit_vcd_partial_c_2=NULL; return(V_END); }
442 		if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue;
443 		break;
444 		}
445 	}
446 	else
447 	{
448 	ch=GLOBALS->var_prevch_vcd_partial_c_2;
449 	GLOBALS->var_prevch_vcd_partial_c_2=0;
450 	}
451 
452 if(ch=='[') return(V_LB);
453 if(ch==':') return(V_COLON);
454 if(ch==']') return(V_RB);
455 
456 for(GLOBALS->yytext_vcd_partial_c_2[len++]=ch;;GLOBALS->yytext_vcd_partial_c_2[len++]=ch)
457 	{
458 	if(len==GLOBALS->T_MAX_STR_vcd_partial_c_2)
459 		{
460 		GLOBALS->yytext_vcd_partial_c_2=(char *)realloc_2(GLOBALS->yytext_vcd_partial_c_2, (GLOBALS->T_MAX_STR_vcd_partial_c_2=GLOBALS->T_MAX_STR_vcd_partial_c_2*2)+1);
461 		}
462 	ch=getch_patched();
463 	if(ch<0) { free_2(GLOBALS->varsplit_vcd_partial_c_2); GLOBALS->varsplit_vcd_partial_c_2=NULL; break; }
464 	if((ch==':')||(ch==']'))
465 		{
466 		GLOBALS->var_prevch_vcd_partial_c_2=ch;
467 		break;
468 		}
469 	}
470 GLOBALS->yytext_vcd_partial_c_2[len]=0;	/* terminator */
471 
472 if(match_kw)
473 	{
474 	int vt = vcd_keyword_code(GLOBALS->yytext_vcd_partial_c_2, len);
475 	if(vt != V_STRING)
476 		{
477 		if(ch<0) { free_2(GLOBALS->varsplit_vcd_partial_c_2); GLOBALS->varsplit_vcd_partial_c_2=NULL; }
478 		return(vt);
479 		}
480 	}
481 
482 GLOBALS->yylen_vcd_partial_c_2=len;
483 if(ch<0) { free_2(GLOBALS->varsplit_vcd_partial_c_2); GLOBALS->varsplit_vcd_partial_c_2=NULL; }
484 return(V_STRING);
485 }
486 
get_vartoken(int match_kw)487 static int get_vartoken(int match_kw)
488 {
489 int ch;
490 int len=0;
491 
492 if(GLOBALS->varsplit_vcd_partial_c_2)
493 	{
494 	int rc=get_vartoken_patched(match_kw);
495 	if(rc!=V_END) return(rc);
496 	GLOBALS->var_prevch_vcd_partial_c_2=0;
497 	}
498 
499 if(!GLOBALS->var_prevch_vcd_partial_c_2)
500 	{
501 	for(;;)
502 		{
503 		ch=getch();
504 		if(ch<0) return(V_END);
505 		if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue;
506 		break;
507 		}
508 	}
509 	else
510 	{
511 	ch=GLOBALS->var_prevch_vcd_partial_c_2;
512 	GLOBALS->var_prevch_vcd_partial_c_2=0;
513 	}
514 
515 if(ch=='[') return(V_LB);
516 if(ch==':') return(V_COLON);
517 if(ch==']') return(V_RB);
518 
519 if(ch=='#')     /* for MTI System Verilog '$var reg 64 >w #implicit-var###VarElem:ram_di[0.0] [63:0] $end' style declarations */
520         {       /* debussy simply escapes until the space */
521         GLOBALS->yytext_vcd_partial_c_2[len++]= '\\';
522         }
523 
524 for(GLOBALS->yytext_vcd_partial_c_2[len++]=ch;;GLOBALS->yytext_vcd_partial_c_2[len++]=ch)
525 	{
526 	if(len==GLOBALS->T_MAX_STR_vcd_partial_c_2)
527 		{
528 		GLOBALS->yytext_vcd_partial_c_2=(char *)realloc_2(GLOBALS->yytext_vcd_partial_c_2, (GLOBALS->T_MAX_STR_vcd_partial_c_2=GLOBALS->T_MAX_STR_vcd_partial_c_2*2)+1);
529 		}
530 
531 	ch=getch();
532         if(ch==' ')
533                 {
534                 if(match_kw) break;
535                 if(getch_peek() == '[')
536                         {
537                         ch = getch();
538                         GLOBALS->varsplit_vcd_partial_c_2=GLOBALS->yytext_vcd_partial_c_2+len; /* keep looping so we get the *last* one */
539                         continue;
540                         }
541                 }
542 
543 	if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break;
544 	if((ch=='[')&&(GLOBALS->yytext_vcd_partial_c_2[0]!='\\'))
545 		{
546 		GLOBALS->varsplit_vcd_partial_c_2=GLOBALS->yytext_vcd_partial_c_2+len;		/* keep looping so we get the *last* one */
547 		}
548 	else
549 	if(((ch==':')||(ch==']'))&&(!GLOBALS->varsplit_vcd_partial_c_2)&&(GLOBALS->yytext_vcd_partial_c_2[0]!='\\'))
550 		{
551 		GLOBALS->var_prevch_vcd_partial_c_2=ch;
552 		break;
553 		}
554 	}
555 GLOBALS->yytext_vcd_partial_c_2[len]=0;	/* absolute terminator */
556 if((GLOBALS->varsplit_vcd_partial_c_2)&&(GLOBALS->yytext_vcd_partial_c_2[len-1]==']'))
557 	{
558 	char *vst;
559 	vst=malloc_2(strlen(GLOBALS->varsplit_vcd_partial_c_2)+1);
560 	strcpy(vst, GLOBALS->varsplit_vcd_partial_c_2);
561 
562 	*GLOBALS->varsplit_vcd_partial_c_2=0x00;		/* zero out var name at the left bracket */
563 	len=GLOBALS->varsplit_vcd_partial_c_2-GLOBALS->yytext_vcd_partial_c_2;
564 
565 	GLOBALS->varsplit_vcd_partial_c_2=GLOBALS->vsplitcurr_vcd_partial_c_2=vst;
566 	GLOBALS->var_prevch_vcd_partial_c_2=0;
567 	}
568 	else
569 	{
570 	GLOBALS->varsplit_vcd_partial_c_2=NULL;
571 	}
572 
573 if(match_kw)
574 	{
575 	int vt = vcd_keyword_code(GLOBALS->yytext_vcd_partial_c_2, len);
576 	if(vt != V_STRING)
577 		{
578 		return(vt);
579 		}
580 	}
581 
582 GLOBALS->yylen_vcd_partial_c_2=len;
583 return(V_STRING);
584 }
585 
get_strtoken(void)586 static int get_strtoken(void)
587 {
588 int ch;
589 int len=0;
590 
591 if(!GLOBALS->var_prevch_vcd_partial_c_2)
592       {
593       for(;;)
594               {
595               ch=getch();
596               if(ch<0) return(V_END);
597               if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue;
598               break;
599               }
600       }
601       else
602       {
603       ch=GLOBALS->var_prevch_vcd_partial_c_2;
604       GLOBALS->var_prevch_vcd_partial_c_2=0;
605       }
606 
607 for(GLOBALS->yytext_vcd_partial_c_2[len++]=ch;;GLOBALS->yytext_vcd_partial_c_2[len++]=ch)
608       {
609 	if(len==GLOBALS->T_MAX_STR_vcd_partial_c_2)
610 		{
611 		GLOBALS->yytext_vcd_partial_c_2=(char *)realloc_2(GLOBALS->yytext_vcd_partial_c_2, (GLOBALS->T_MAX_STR_vcd_partial_c_2=GLOBALS->T_MAX_STR_vcd_partial_c_2*2)+1);
612 		}
613       ch=getch();
614       if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break;
615       }
616 GLOBALS->yytext_vcd_partial_c_2[len]=0;        /* terminator */
617 
618 GLOBALS->yylen_vcd_partial_c_2=len;
619 return(V_STRING);
620 }
621 
sync_end(char * hdr)622 static void sync_end(char *hdr)
623 {
624 int tok;
625 
626 if(hdr) { DEBUG(fprintf(stderr,"%s",hdr)); }
627 for(;;)
628 	{
629 	tok=get_token();
630 	if((tok==T_END)||(tok==T_EOF)) break;
631 	if(hdr) { DEBUG(fprintf(stderr," %s",GLOBALS->yytext_vcd_partial_c_2)); }
632 	}
633 if(hdr) { DEBUG(fprintf(stderr,"\n")); }
634 }
635 
version_sync_end(char * hdr)636 static int version_sync_end(char *hdr)
637 {
638 int tok;
639 int rc = 0;
640 
641 if(hdr) { DEBUG(fprintf(stderr,"%s",hdr)); }
642 for(;;)
643 	{
644 	tok=get_token();
645 	if((tok==T_END)||(tok==T_EOF)) break;
646 	if(hdr) { DEBUG(fprintf(stderr," %s",GLOBALS->yytext_vcd_partial_c_2)); }
647         if(strstr(GLOBALS->yytext_vcd_partial_c_2, "Icarus"))   /* turn off autocoalesce for Icarus */
648                 {
649 		GLOBALS->autocoalesce = 0;
650                 rc = 1;
651                 }
652 	}
653 if(hdr) { DEBUG(fprintf(stderr,"\n")); }
654 return(rc);
655 }
656 
657 
parse_valuechange(void)658 static void parse_valuechange(void)
659 {
660 struct vcdsymbol *v;
661 char *vector;
662 int vlen;
663 /* hptr hsuf; */ /* scan-build */
664 
665 switch(GLOBALS->yytext_vcd_partial_c_2[0])
666 	{
667 	case '0':
668 	case '1':
669 	case 'x': case 'X':
670 	case 'z': case 'Z':
671 	case 'h': case 'H':
672 	case 'u': case 'U':
673 	case 'w': case 'W':
674 	case 'l': case 'L':
675 	case '-':
676 		if(GLOBALS->yylen_vcd_partial_c_2>1)
677 			{
678 			v=bsearch_vcd(GLOBALS->yytext_vcd_partial_c_2+1, GLOBALS->yylen_vcd_partial_c_2-1);
679 			if(!v)
680 				{
681 				fprintf(stderr,"Near byte %d, Unknown VCD identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)),GLOBALS->yytext_vcd_partial_c_2+1);
682 				}
683 				else
684 				{
685 				v->value[0]=GLOBALS->yytext_vcd_partial_c_2[0];
686 				DEBUG(fprintf(stderr,"%s = '%c'\n",v->name,v->value[0]));
687 
688 				v->narray[0]->curr = v->app_array[0];
689 				/* hsuf = */ add_histent_p(GLOBALS->current_time_vcd_partial_c_2,v->narray[0],v->value[0],1, NULL); /* scan-build */
690 				v->app_array[0] = v->narray[0]->curr;
691 				v->narray[0]->curr->next = v->tr_array[0];
692 				if(v->narray[0]->harray) { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; }
693 				}
694 			}
695 			else
696 			{
697 			fprintf(stderr,"Near byte %d, Malformed VCD identifier\n", (int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)));
698 			}
699 		break;
700 
701 	case 'b':
702 	case 'B':
703 		{
704 		/* extract binary number then.. */
705 		vector=malloc_2(GLOBALS->yylen_cache_vcd_partial_c_2=GLOBALS->yylen_vcd_partial_c_2);
706 		strcpy(vector,GLOBALS->yytext_vcd_partial_c_2+1);
707 		vlen=GLOBALS->yylen_vcd_partial_c_2-1;
708 
709 		get_strtoken();
710 		v=bsearch_vcd(GLOBALS->yytext_vcd_partial_c_2, GLOBALS->yylen_vcd_partial_c_2);
711 		if(!v)
712 			{
713 			fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), GLOBALS->yytext_vcd_partial_c_2);
714 			free_2(vector);
715 			}
716 			else
717 			{
718 			if ((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)||((GLOBALS->convert_to_reals)&&((v->vartype==V_INTEGER)||(v->vartype==V_PARAMETER))))
719 				{
720 				double *d;
721 				char *pnt;
722 				char ch;
723 				TimeType k=0;
724 
725 				pnt=vector;
726 				while((ch=*(pnt++))) { k=(k<<1)|((ch=='1')?1:0); }
727 				free_2(vector);
728 
729 				d=malloc_2(sizeof(double));
730 				*d=(double)k;
731 
732 				if(!v)
733 					{
734 					fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), GLOBALS->yytext_vcd_partial_c_2);
735 					free_2(d);
736 					}
737 					else
738 					{
739 					v->narray[0]->curr = v->app_array[0];
740 					add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[0],'g',1,(char *)d);
741 					v->app_array[0] = v->narray[0]->curr;
742 					v->narray[0]->curr->next = v->tr_array[0];
743 					if(v->narray[0]->harray)
744 					        { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; }
745 					}
746 				break;
747 				}
748 
749 			if(vlen<v->size) 	/* fill in left part */
750 				{
751 				char extend;
752 				int i, fill;
753 
754 				extend=(vector[0]=='1')?'0':vector[0];
755 
756 				fill=v->size-vlen;
757 				for(i=0;i<fill;i++)
758 					{
759 					v->value[i]=extend;
760 					}
761 				strcpy(v->value+fill,vector);
762 				}
763 			else if(vlen==v->size) 	/* straight copy */
764 				{
765 				strcpy(v->value,vector);
766 				}
767 			else			/* too big, so copy only right half */
768 				{
769 				int skip;
770 
771 				skip=vlen-v->size;
772 				strcpy(v->value,vector+skip);
773 				}
774 			DEBUG(fprintf(stderr,"%s = '%s'\n",v->name, v->value));
775 
776 			if((v->size==1)||(!GLOBALS->atomic_vectors))
777 				{
778 				int i;
779 				for(i=0;i<v->size;i++)
780 					{
781 					v->narray[i]->curr = v->app_array[i];
782 					add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[i],v->value[i],1, NULL);
783 					v->app_array[i] = v->narray[i]->curr;
784 					v->narray[i]->curr->next = v->tr_array[i];
785 					if(v->narray[i]->harray)
786 					        { free_2(v->narray[i]->harray); v->narray[i]->harray = NULL; }
787 					}
788 				free_2(vector);
789 				}
790 				else
791 				{
792 				if(GLOBALS->yylen_cache_vcd_partial_c_2!=(v->size+1))
793 					{
794 					free_2(vector);
795 					vector=malloc_2(v->size+1);
796 					}
797 				strcpy(vector,v->value);
798 				v->narray[0]->curr = v->app_array[0];
799 				add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[0],0,1,vector);
800 				v->app_array[0] = v->narray[0]->curr;
801 				v->narray[0]->curr->next = v->tr_array[0];
802 				if(v->narray[0]->harray)
803 				        { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; }
804 				}
805 
806 			}
807 		break;
808 		}
809 
810 	case 'p':
811 		/* extract port dump value.. */
812 		vector=malloc_2(GLOBALS->yylen_cache_vcd_partial_c_2=GLOBALS->yylen_vcd_partial_c_2);
813 		strcpy(vector,GLOBALS->yytext_vcd_partial_c_2+1);
814 		vlen=GLOBALS->yylen_vcd_partial_c_2-1;
815 
816 		get_strtoken();	/* throw away 0_strength_component */
817 		get_strtoken(); /* throw away 0_strength_component */
818 		get_strtoken(); /* this is the id                  */
819 		v=bsearch_vcd(GLOBALS->yytext_vcd_partial_c_2, GLOBALS->yylen_vcd_partial_c_2);
820 		if(!v)
821 			{
822 			fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), GLOBALS->yytext_vcd_partial_c_2);
823 			free_2(vector);
824 			}
825 			else
826 			{
827 			if ((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)||((GLOBALS->convert_to_reals)&&((v->vartype==V_INTEGER)||(v->vartype==V_PARAMETER))))
828 				{
829 				double *d;
830 				char *pnt;
831 				char ch;
832 				TimeType k=0;
833 
834 				pnt=vector;
835 				while((ch=*(pnt++))) { k=(k<<1)|((ch=='1')?1:0); }
836 				free_2(vector);
837 
838 				d=malloc_2(sizeof(double));
839 				*d=(double)k;
840 
841 				if(!v)
842 					{
843 					fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), GLOBALS->yytext_vcd_partial_c_2);
844 					free_2(d);
845 					}
846 					else
847 					{
848 					v->narray[0]->curr = v->app_array[0];
849 					add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[0],'g',1,(char *)d);
850 					v->app_array[0] = v->narray[0]->curr;
851 					v->narray[0]->curr->next = v->tr_array[0];
852 					if(v->narray[0]->harray)
853 					        { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; }
854 					}
855 				break;
856 				}
857 
858 			if(vlen<v->size) 	/* fill in left part */
859 				{
860 				char extend;
861 				int i, fill;
862 
863 				extend='0';
864 
865 				fill=v->size-vlen;
866 				for(i=0;i<fill;i++)
867 					{
868 					v->value[i]=extend;
869 					}
870 				evcd_strcpy(v->value+fill,vector);
871 				}
872 			else if(vlen==v->size) 	/* straight copy */
873 				{
874 				evcd_strcpy(v->value,vector);
875 				}
876 			else			/* too big, so copy only right half */
877 				{
878 				int skip;
879 
880 				skip=vlen-v->size;
881 				evcd_strcpy(v->value,vector+skip);
882 				}
883 			DEBUG(fprintf(stderr,"%s = '%s'\n",v->name, v->value));
884 
885 			if((v->size==1)||(!GLOBALS->atomic_vectors))
886 				{
887 				int i;
888 				for(i=0;i<v->size;i++)
889 					{
890 					v->narray[i]->curr = v->app_array[i];
891 					add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[i],v->value[i],1, NULL);
892 					v->app_array[i] = v->narray[i]->curr;
893 					v->narray[i]->curr->next = v->tr_array[i];
894 					if(v->narray[i]->harray)
895 					        { free_2(v->narray[i]->harray); v->narray[i]->harray = NULL; }
896 					}
897 				free_2(vector);
898 				}
899 				else
900 				{
901 				if(GLOBALS->yylen_cache_vcd_partial_c_2<v->size)
902 					{
903 					free_2(vector);
904 					vector=malloc_2(v->size+1);
905 					}
906 				strcpy(vector,v->value);
907 				v->narray[0]->curr = v->app_array[0];
908 				add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[0],0,1,vector);
909 				v->app_array[0] = v->narray[0]->curr;
910 				v->narray[0]->curr->next = v->tr_array[0];
911 				if(v->narray[0]->harray)
912 				        { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; }
913 				}
914 			}
915 		break;
916 
917 
918 	case 'r':
919 	case 'R':
920 		{
921 		double *d;
922 
923 		d=malloc_2(sizeof(double));
924 		sscanf(GLOBALS->yytext_vcd_partial_c_2+1,"%lg",d);
925 
926 		get_strtoken();
927 		v=bsearch_vcd(GLOBALS->yytext_vcd_partial_c_2, GLOBALS->yylen_vcd_partial_c_2);
928 		if(!v)
929 			{
930 			fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), GLOBALS->yytext_vcd_partial_c_2);
931 			free_2(d);
932 			}
933 			else
934 			{
935 			v->narray[0]->curr = v->app_array[0];
936 			add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[0],'g',1,(char *)d);
937 			v->app_array[0] = v->narray[0]->curr;
938 			v->narray[0]->curr->next = v->tr_array[0];
939 			if(v->narray[0]->harray)
940 			        { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; }
941 			}
942 
943 		break;
944 		}
945 
946 #ifndef STRICT_VCD_ONLY
947 	case 's':
948 	case 'S':
949 		{
950 		char *d;
951 
952                 d=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2);
953                 vlen = fstUtilityEscToBin((unsigned char *)d, (unsigned char *)(GLOBALS->yytext_vcd_partial_c_2+1), GLOBALS->yylen_vcd_partial_c_2); /* includes 0 term */
954                 if(vlen != GLOBALS->yylen_vcd_partial_c_2)
955                         {
956                         d = realloc_2(d, vlen);
957                         }
958 
959 		get_strtoken();
960 		v=bsearch_vcd(GLOBALS->yytext_vcd_partial_c_2, GLOBALS->yylen_vcd_partial_c_2);
961 		if(!v)
962 			{
963 			fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), GLOBALS->yytext_vcd_partial_c_2);
964 			free_2(d);
965 			}
966 			else
967 			{
968 			v->narray[0]->curr = v->app_array[0];
969 			add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[0],'s',1,(char *)d);
970 			v->app_array[0] = v->narray[0]->curr;
971 			v->narray[0]->curr->next = v->tr_array[0];
972 			if(v->narray[0]->harray)
973 			        { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; }
974 			}
975 
976 		break;
977 		}
978 #endif
979 	}
980 
981 }
982 
983 
evcd_strcpy(char * dst,char * src)984 static void evcd_strcpy(char *dst, char *src)
985 {
986 static const char *evcd="DUNZduLHXTlh01?FAaBbCcf";
987 static const char  *vcd="01xz0101xz0101xzxxxxxxz";
988 
989 char ch;
990 int i;
991 
992 while((ch=*src))
993 	{
994 	for(i=0;i<23;i++)
995 		{
996 		if(evcd[i]==ch)
997 			{
998 			*dst=vcd[i];
999 			break;
1000 			}
1001 		}
1002 	if(i==23) *dst='x';
1003 
1004 	src++;
1005 	dst++;
1006 	}
1007 
1008 *dst=0;	/* null terminate destination */
1009 }
1010 
1011 
vcd_parse(void)1012 static void vcd_parse(void)
1013 {
1014 int tok;
1015 unsigned char ttype;
1016 int disable_autocoalesce = 0;
1017 
1018 for(;;)
1019 	{
1020 	switch(get_token())
1021 		{
1022 		case T_COMMENT:
1023 			sync_end("COMMENT:");
1024 			break;
1025 		case T_DATE:
1026 			sync_end("DATE:");
1027 			break;
1028 		case T_VERSION:
1029 			disable_autocoalesce = version_sync_end("VERSION:");
1030 			break;
1031                 case T_TIMEZERO:
1032                         {
1033                         int vtok=get_token();
1034                         if((vtok==T_END)||(vtok==T_EOF)) break;
1035                         GLOBALS->global_time_offset=atoi_64(GLOBALS->yytext_vcd_partial_c_2);
1036 
1037                         DEBUG(fprintf(stderr,"TIMEZERO: "TTFormat"\n",GLOBALS->global_time_offset));
1038                         sync_end(NULL);
1039                         }
1040                         break;
1041 		case T_TIMESCALE:
1042 			{
1043 			int vtok;
1044 			int i;
1045 			char prefix=' ';
1046 
1047 			vtok=get_token();
1048 			if((vtok==T_END)||(vtok==T_EOF)) break;
1049 			fractional_timescale_fix(GLOBALS->yytext_vcd_partial_c_2);
1050 			GLOBALS->time_scale=atoi_64(GLOBALS->yytext_vcd_partial_c_2);
1051 			if(!GLOBALS->time_scale) GLOBALS->time_scale=1;
1052 			for(i=0;i<GLOBALS->yylen_vcd_partial_c_2;i++)
1053 				{
1054 				if((GLOBALS->yytext_vcd_partial_c_2[i]<'0')||(GLOBALS->yytext_vcd_partial_c_2[i]>'9'))
1055 					{
1056 					prefix=GLOBALS->yytext_vcd_partial_c_2[i];
1057 					break;
1058 					}
1059 				}
1060 			if(prefix==' ')
1061 				{
1062 				vtok=get_token();
1063 				if((vtok==T_END)||(vtok==T_EOF)) break;
1064 				prefix=GLOBALS->yytext_vcd_partial_c_2[0];
1065 				}
1066 			switch(prefix)
1067 				{
1068 				case ' ':
1069 				case 'm':
1070 				case 'u':
1071 				case 'n':
1072 				case 'p':
1073 				case 'f':
1074 				case 'a':
1075 				case 'z':
1076 					GLOBALS->time_dimension=prefix;
1077 					break;
1078 				case 's':
1079 					GLOBALS->time_dimension=' ';
1080 					break;
1081 				default:	/* unknown */
1082 					GLOBALS->time_dimension='n';
1083 					break;
1084 				}
1085 
1086 			DEBUG(fprintf(stderr,"TIMESCALE: "TTFormat" %cs\n",GLOBALS->time_scale, GLOBALS->time_dimension));
1087 			sync_end(NULL);
1088 			}
1089 			break;
1090 		case T_SCOPE:
1091 			T_GET;
1092                                 {
1093                                 switch(GLOBALS->yytext_vcd_partial_c_2[0])
1094                                         {
1095                                         case 'm':       ttype = TREE_VCD_ST_MODULE; break;
1096                                         case 't':       ttype = TREE_VCD_ST_TASK; break;
1097                                         case 'f':       ttype = (GLOBALS->yytext_vcd_partial_c_2[1] == 'u') ? TREE_VCD_ST_FUNCTION : TREE_VCD_ST_FORK; break;
1098                                         case 'b':       ttype = TREE_VCD_ST_BEGIN; break;
1099 					case 'g':       ttype = TREE_VCD_ST_GENERATE; break;
1100 					case 's':       ttype = TREE_VCD_ST_STRUCT; break;
1101 					case 'u':       ttype = TREE_VCD_ST_UNION; break;
1102 					case 'c':       ttype = TREE_VCD_ST_CLASS; break;
1103 					case 'i':       ttype = TREE_VCD_ST_INTERFACE; break;
1104 					case 'p':       ttype = (GLOBALS->yytext_vcd_partial_c_2[1] == 'r') ? TREE_VCD_ST_PROGRAM : TREE_VCD_ST_PACKAGE; break;
1105 
1106                                         case 'v':       {
1107                                                         char *vht = GLOBALS->yytext_vcd_partial_c_2;
1108                                                         if(!strncmp(vht, "vhdl_", 5))
1109                                                                 {
1110                                                                 switch(vht[5])
1111                                                                         {
1112                                                                         case 'a':       ttype = TREE_VHDL_ST_ARCHITECTURE; break;
1113                                                                         case 'r':       ttype = TREE_VHDL_ST_RECORD; break;
1114                                                                         case 'b':       ttype = TREE_VHDL_ST_BLOCK; break;
1115                                                                         case 'g':       ttype = TREE_VHDL_ST_GENERATE; break;
1116                                                                         case 'i':       ttype = TREE_VHDL_ST_GENIF; break;
1117                                                                         case 'f':       ttype = (vht[6] == 'u') ? TREE_VHDL_ST_FUNCTION : TREE_VHDL_ST_GENFOR; break;
1118 		                                                       	case 'p':       ttype = (!strncmp(vht+6, "roces", 5)) ? TREE_VHDL_ST_PROCESS: TREE_VHDL_ST_PROCEDURE; break;
1119                                                                         default:        ttype = TREE_UNKNOWN; break;
1120                                                                         }
1121                                                                 }
1122                                                                 else
1123                                                                 {
1124                                                                 ttype = TREE_UNKNOWN;
1125                                                                 }
1126                                                         }
1127                                                         break;
1128 
1129                                         default:        ttype = TREE_UNKNOWN;
1130                                                         break;
1131                                         }
1132                                 }
1133 			T_GET;
1134 			if(tok==T_STRING)
1135 				{
1136 				struct slist *s;
1137 				s=(struct slist *)calloc_2(1,sizeof(struct slist));
1138 				s->len=GLOBALS->yylen_vcd_partial_c_2;
1139 				s->str=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+1);
1140 				strcpy(s->str, GLOBALS->yytext_vcd_partial_c_2);
1141 				s->mod_tree_parent = GLOBALS->mod_tree_parent;
1142 
1143 				allocate_and_decorate_module_tree_node(ttype, GLOBALS->yytext_vcd_partial_c_2, NULL, GLOBALS->yylen_vcd_partial_c_2, 0, 0, 0);
1144 
1145 				if(GLOBALS->slistcurr)
1146 					{
1147 					GLOBALS->slistcurr->next=s;
1148 					GLOBALS->slistcurr=s;
1149 					}
1150 					else
1151 					{
1152 					GLOBALS->slistcurr=GLOBALS->slistroot=s;
1153 					}
1154 
1155 				build_slisthier();
1156 				DEBUG(fprintf(stderr, "SCOPE: %s\n",GLOBALS->slisthier));
1157 				}
1158 			sync_end(NULL);
1159 			break;
1160 		case T_UPSCOPE:
1161 			if(GLOBALS->slistroot)
1162 				{
1163 				struct slist *s;
1164 
1165 				GLOBALS->mod_tree_parent = GLOBALS->slistcurr->mod_tree_parent;
1166 				s=GLOBALS->slistroot;
1167 				if(!s->next)
1168 					{
1169 					free_2(s->str);
1170 					free_2(s);
1171 					GLOBALS->slistroot=GLOBALS->slistcurr=NULL;
1172 					}
1173 				else
1174 				for(;;)
1175 					{
1176 					if(!s->next->next)
1177 						{
1178 						free_2(s->next->str);
1179 						free_2(s->next);
1180 						s->next=NULL;
1181 						GLOBALS->slistcurr=s;
1182 						break;
1183 						}
1184 					s=s->next;
1185 					}
1186 				build_slisthier();
1187 				DEBUG(fprintf(stderr, "SCOPE: %s\n",GLOBALS->slisthier));
1188 				}
1189 				else
1190 				{
1191 				GLOBALS->mod_tree_parent = NULL;
1192 				}
1193 			sync_end(NULL);
1194 			break;
1195 		case T_VAR:
1196 			if((GLOBALS->header_over_vcd_partial_c_2)&&(0))
1197 			{
1198 			fprintf(stderr,"$VAR encountered after $ENDDEFINITIONS near byte %d.  VCD is malformed, exiting.\n",
1199 				(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)));
1200 			exit(0);
1201 			}
1202 			else
1203 			{
1204 			int vtok;
1205 			struct vcdsymbol *v=NULL;
1206 
1207 			GLOBALS->var_prevch_vcd_partial_c_2=0;
1208 			if(GLOBALS->varsplit_vcd_partial_c_2)
1209 				{
1210 				free_2(GLOBALS->varsplit_vcd_partial_c_2);
1211 				GLOBALS->varsplit_vcd_partial_c_2=NULL;
1212 				}
1213 			vtok=get_vartoken(1);
1214 			if(vtok>V_STRINGTYPE) goto bail;
1215 
1216 			v=(struct vcdsymbol *)calloc_2(1,sizeof(struct vcdsymbol));
1217 			v->vartype=vtok;
1218 			v->msi=v->lsi=GLOBALS->vcd_explicit_zero_subscripts; /* indicate [un]subscripted status */
1219 
1220 			if(vtok==V_PORT)
1221 				{
1222 				vtok=get_vartoken(1);
1223 				if(vtok==V_STRING)
1224 					{
1225 					v->size=atoi_64(GLOBALS->yytext_vcd_partial_c_2);
1226 					if(!v->size) v->size=1;
1227 					}
1228 					else
1229 					if(vtok==V_LB)
1230 					{
1231 					vtok=get_vartoken(1);
1232 					if(vtok==V_END) goto err;
1233 					if(vtok!=V_STRING) goto err;
1234 					v->msi=atoi_64(GLOBALS->yytext_vcd_partial_c_2);
1235 					vtok=get_vartoken(0);
1236 					if(vtok==V_RB)
1237 						{
1238 						v->lsi=v->msi;
1239 						v->size=1;
1240 						}
1241 						else
1242 						{
1243 						if(vtok!=V_COLON) goto err;
1244 						vtok=get_vartoken(0);
1245 						if(vtok!=V_STRING) goto err;
1246 						v->lsi=atoi_64(GLOBALS->yytext_vcd_partial_c_2);
1247 						vtok=get_vartoken(0);
1248 						if(vtok!=V_RB) goto err;
1249 
1250 						if(v->msi>v->lsi)
1251 							{
1252 							v->size=v->msi-v->lsi+1;
1253 							}
1254 							else
1255 							{
1256 							v->size=v->lsi-v->msi+1;
1257 							}
1258 						}
1259 					}
1260 					else goto err;
1261 
1262 				vtok=get_strtoken();
1263 				if(vtok==V_END) goto err;
1264 				v->id=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+1);
1265 				strcpy(v->id, GLOBALS->yytext_vcd_partial_c_2);
1266                                 v->nid=vcdid_hash(GLOBALS->yytext_vcd_partial_c_2,GLOBALS->yylen_vcd_partial_c_2);
1267 
1268                                 if(v->nid == (GLOBALS->vcd_hash_max+1))
1269                                         {
1270                                         GLOBALS->vcd_hash_max = v->nid;
1271                                         }
1272                                 else
1273                                 if((v->nid>0)&&(v->nid<=GLOBALS->vcd_hash_max))
1274                                         {
1275                                         /* general case with aliases */
1276                                         }
1277                                 else
1278                                         {
1279                                         GLOBALS->vcd_hash_kill = 1;
1280                                         }
1281 
1282                                 if(v->nid < GLOBALS->vcd_minid_vcd_partial_c_2) GLOBALS->vcd_minid_vcd_partial_c_2 = v->nid;
1283                                 if(v->nid > GLOBALS->vcd_maxid_vcd_partial_c_2) GLOBALS->vcd_maxid_vcd_partial_c_2 = v->nid;
1284 
1285 				vtok=get_vartoken(0);
1286 				if(vtok!=V_STRING) goto err;
1287 				if(GLOBALS->slisthier_len)
1288 					{
1289 					v->name=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_partial_c_2+1);
1290 					strcpy(v->name,GLOBALS->slisthier);
1291 					strcpy(v->name+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter);
1292 					if(GLOBALS->alt_hier_delimeter)
1293 						{
1294 						strcpy_vcdalt(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_partial_c_2,GLOBALS->alt_hier_delimeter);
1295 						}
1296 						else
1297 						{
1298 						if((strcpy_delimfix(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_partial_c_2)) && (GLOBALS->yytext_vcd_partial_c_2[0] != '\\'))
1299 							{
1300 							char *sd=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_partial_c_2+2);
1301 							strcpy(sd,GLOBALS->slisthier);
1302 							strcpy(sd+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter);
1303 							sd[GLOBALS->slisthier_len+1] = '\\';
1304 							strcpy(sd+GLOBALS->slisthier_len+2,v->name+GLOBALS->slisthier_len+1);
1305 							free_2(v->name);
1306 							v->name = sd;
1307 							}
1308 						}
1309 					}
1310 					else
1311 					{
1312 					v->name=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+1);
1313 					if(GLOBALS->alt_hier_delimeter)
1314 						{
1315 						strcpy_vcdalt(v->name,GLOBALS->yytext_vcd_partial_c_2,GLOBALS->alt_hier_delimeter);
1316 						}
1317 						else
1318 						{
1319 						if((strcpy_delimfix(v->name,GLOBALS->yytext_vcd_partial_c_2)) && (GLOBALS->yytext_vcd_partial_c_2[0] != '\\'))
1320 							{
1321 							char *sd=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+2);
1322 							sd[0] = '\\';
1323 							strcpy(sd+1,v->name);
1324 							free_2(v->name);
1325 							v->name = sd;
1326 							}
1327 						}
1328 					}
1329 
1330                                 if(GLOBALS->pv_vcd_partial_c_2)
1331                                         {
1332                                         if(!strcmp(GLOBALS->pv_vcd_partial_c_2->name,v->name) && !disable_autocoalesce && (!strchr(v->name, '\\')))
1333                                                 {
1334                                                 GLOBALS->pv_vcd_partial_c_2->chain=v;
1335                                                 v->root=GLOBALS->rootv_vcd_partial_c_2;
1336                                                 if(GLOBALS->pv_vcd_partial_c_2==GLOBALS->rootv_vcd_partial_c_2) GLOBALS->pv_vcd_partial_c_2->root=GLOBALS->rootv_vcd_partial_c_2;
1337                                                 }
1338                                                 else
1339                                                 {
1340                                                 GLOBALS->rootv_vcd_partial_c_2=v;
1341                                                 }
1342                                         }
1343 					else
1344 					{
1345 					GLOBALS->rootv_vcd_partial_c_2=v;
1346 					}
1347                                 GLOBALS->pv_vcd_partial_c_2=v;
1348 				}
1349 				else	/* regular vcd var, not an evcd port var */
1350 				{
1351 				vtok=get_vartoken(1);
1352 				if(vtok==V_END) goto err;
1353 				v->size=atoi_64(GLOBALS->yytext_vcd_partial_c_2);
1354 				vtok=get_strtoken();
1355 				if(vtok==V_END) goto err;
1356 				v->id=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+1);
1357 				strcpy(v->id, GLOBALS->yytext_vcd_partial_c_2);
1358                                 v->nid=vcdid_hash(GLOBALS->yytext_vcd_partial_c_2,GLOBALS->yylen_vcd_partial_c_2);
1359 
1360                                 if(v->nid == (GLOBALS->vcd_hash_max+1))
1361                                         {
1362                                         GLOBALS->vcd_hash_max = v->nid;
1363                                         }
1364                                 else
1365                                 if((v->nid>0)&&(v->nid<=GLOBALS->vcd_hash_max))
1366                                         {
1367                                         /* general case with aliases */
1368                                         }
1369                                 else
1370                                         {
1371                                         GLOBALS->vcd_hash_kill = 1;
1372                                         }
1373 
1374                                 if(v->nid < GLOBALS->vcd_minid_vcd_partial_c_2) GLOBALS->vcd_minid_vcd_partial_c_2 = v->nid;
1375                                 if(v->nid > GLOBALS->vcd_maxid_vcd_partial_c_2) GLOBALS->vcd_maxid_vcd_partial_c_2 = v->nid;
1376 
1377 				vtok=get_vartoken(0);
1378 				if(vtok!=V_STRING) goto err;
1379 				if(GLOBALS->slisthier_len)
1380 					{
1381 					v->name=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_partial_c_2+1);
1382 					strcpy(v->name,GLOBALS->slisthier);
1383 					strcpy(v->name+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter);
1384 					if(GLOBALS->alt_hier_delimeter)
1385 						{
1386 						strcpy_vcdalt(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_partial_c_2,GLOBALS->alt_hier_delimeter);
1387 						}
1388 						else
1389 						{
1390 						if((strcpy_delimfix(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_partial_c_2)) && (GLOBALS->yytext_vcd_partial_c_2[0] != '\\'))
1391 							{
1392                                                         char *sd=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_partial_c_2+2);
1393                                                         strcpy(sd,GLOBALS->slisthier);
1394                                                         strcpy(sd+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter);
1395                                                         sd[GLOBALS->slisthier_len+1] = '\\';
1396                                                         strcpy(sd+GLOBALS->slisthier_len+2,v->name+GLOBALS->slisthier_len+1);
1397                                                         free_2(v->name);
1398                                                         v->name = sd;
1399 							}
1400 						}
1401 					}
1402 					else
1403 					{
1404 					v->name=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+1);
1405 					if(GLOBALS->alt_hier_delimeter)
1406 						{
1407 						strcpy_vcdalt(v->name,GLOBALS->yytext_vcd_partial_c_2,GLOBALS->alt_hier_delimeter);
1408 						}
1409 						else
1410 						{
1411                                                 if((strcpy_delimfix(v->name,GLOBALS->yytext_vcd_partial_c_2)) && (GLOBALS->yytext_vcd_partial_c_2[0] != '\\'))
1412                                                         {
1413                                                         char *sd=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+2);
1414                                                         sd[0] = '\\';
1415                                                         strcpy(sd+1,v->name);
1416                                                         free_2(v->name);
1417                                                         v->name = sd;
1418                                                         }
1419 						}
1420 					}
1421 
1422                                 if(GLOBALS->pv_vcd_partial_c_2)
1423                                         {
1424                                         if(!strcmp(GLOBALS->pv_vcd_partial_c_2->name,v->name))
1425                                                 {
1426                                                 GLOBALS->pv_vcd_partial_c_2->chain=v;
1427                                                 v->root=GLOBALS->rootv_vcd_partial_c_2;
1428                                                 if(GLOBALS->pv_vcd_partial_c_2==GLOBALS->rootv_vcd_partial_c_2) GLOBALS->pv_vcd_partial_c_2->root=GLOBALS->rootv_vcd_partial_c_2;
1429                                                 }
1430                                                 else
1431                                                 {
1432                                                 GLOBALS->rootv_vcd_partial_c_2=v;
1433                                                 }
1434                                         }
1435 					else
1436 					{
1437 					GLOBALS->rootv_vcd_partial_c_2=v;
1438 					}
1439                                 GLOBALS->pv_vcd_partial_c_2=v;
1440 
1441 				vtok=get_vartoken(1);
1442 				if(vtok==V_END) goto dumpv;
1443 				if(vtok!=V_LB) goto err;
1444 				vtok=get_vartoken(0);
1445 				if(vtok!=V_STRING) goto err;
1446 				v->msi=atoi_64(GLOBALS->yytext_vcd_partial_c_2);
1447 				vtok=get_vartoken(0);
1448 				if(vtok==V_RB)
1449 					{
1450 					v->lsi=v->msi;
1451 					goto dumpv;
1452 					}
1453 				if(vtok!=V_COLON) goto err;
1454 				vtok=get_vartoken(0);
1455 				if(vtok!=V_STRING) goto err;
1456 				v->lsi=atoi_64(GLOBALS->yytext_vcd_partial_c_2);
1457 				vtok=get_vartoken(0);
1458 				if(vtok!=V_RB) goto err;
1459 				}
1460 
1461 			dumpv:
1462                         if(v->size == 0)
1463                                 {
1464                                 if(v->vartype != V_EVENT)
1465                                         {
1466 					if(v->vartype != V_STRINGTYPE)
1467 						{
1468 	                                        v->vartype = V_REAL;
1469 						}
1470                                         }
1471                                         else
1472                                         {
1473                                         v->size = 1;
1474                                         }
1475 
1476                                 } /* MTI fix */
1477 
1478 			if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)||((GLOBALS->convert_to_reals)&&((v->vartype==V_INTEGER)||(v->vartype==V_PARAMETER))))
1479 				{
1480 				if(v->vartype != V_STRINGTYPE)
1481 					{
1482 					v->vartype=V_REAL;
1483 					}
1484 				v->size=1;		/* override any data we parsed in */
1485 				v->msi=v->lsi=0;
1486 				}
1487 			else
1488 			if((v->size>1)&&(v->msi<=0)&&(v->lsi<=0))
1489 				{
1490 				if(v->vartype==V_EVENT)
1491 					{
1492 					v->size=1;
1493 					}
1494 					else
1495 					{
1496 					/* any criteria for the direction here? */
1497 					v->msi=v->size-1;
1498 					v->lsi=0;
1499 					}
1500 				}
1501 			else
1502 			if((v->msi>v->lsi)&&((v->msi-v->lsi+1)!=v->size))
1503 				{
1504                                 if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER))
1505                                         {
1506 					if((v->msi-v->lsi+1) > v->size) /* if() is 2d add */
1507 						{
1508 	                                        v->msi = v->size-1; v->lsi = 0;
1509 						}
1510                                         /* all this formerly was goto err; */
1511                                         }
1512                                         else
1513                                         {
1514                                         v->size=v->msi-v->lsi+1;
1515                                         }
1516 				}
1517 			else
1518 			if((v->lsi>=v->msi)&&((v->lsi-v->msi+1)!=v->size))
1519 				{
1520                                 if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER))
1521                                         {
1522 					if((v->lsi-v->msi+1) > v->size) /* if() is 2d add */
1523 						{
1524 	                                        v->lsi = v->size-1; v->msi = 0;
1525 						}
1526                                         /* all this formerly was goto err; */
1527                                         }
1528                                         else
1529                                         {
1530                                         v->size=v->lsi-v->msi+1;
1531                                         }
1532 				}
1533 
1534 			/* initial conditions */
1535 			v->value=(char *)malloc_2(v->size+1);
1536 			v->value[v->size]=0;
1537 			v->narray=(struct Node **)calloc_2(v->size,sizeof(struct Node *));
1538 			v->tr_array=(hptr *)calloc_2(v->size,sizeof(hptr));
1539 			v->app_array=(hptr *)calloc_2(v->size,sizeof(hptr));
1540 				{
1541 				int i;
1542 				if(GLOBALS->atomic_vectors)
1543 					{
1544 					for(i=0;i<v->size;i++)
1545 						{
1546 						v->value[i]='x';
1547 						}
1548 					v->narray[0]=(struct Node *)calloc_2(1,sizeof(struct Node));
1549 					v->narray[0]->head.time=-1;
1550 					v->narray[0]->head.v.h_val=AN_X;
1551 					}
1552 					else
1553 					{
1554 					for(i=0;i<v->size;i++)
1555 						{
1556 						v->value[i]='x';
1557 
1558 						v->narray[i]=(struct Node *)calloc_2(1,sizeof(struct Node));
1559 						v->narray[i]->head.time=-1;
1560 						v->narray[i]->head.v.h_val=AN_X;
1561 						}
1562 					}
1563 				}
1564 
1565 			if(!GLOBALS->vcdsymroot_vcd_partial_c_2)
1566 				{
1567 				GLOBALS->vcdsymroot_vcd_partial_c_2=GLOBALS->vcdsymcurr_vcd_partial_c_2=v;
1568 				}
1569 				else
1570 				{
1571 				GLOBALS->vcdsymcurr_vcd_partial_c_2->next=v;
1572 				GLOBALS->vcdsymcurr_vcd_partial_c_2=v;
1573 				}
1574 			GLOBALS->numsyms_vcd_partial_c_2++;
1575 
1576 			goto bail;
1577 			err:
1578 			if(v)
1579 				{
1580 				GLOBALS->error_count_vcd_partial_c_2++;
1581 				if(v->name)
1582 					{
1583 					fprintf(stderr, "Near byte %d, $VAR parse error encountered with '%s'\n", (int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), v->name);
1584 					free_2(v->name);
1585 					}
1586 					else
1587 					{
1588 					fprintf(stderr, "Near byte %d, $VAR parse error encountered\n", (int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)));
1589 					}
1590 				if(v->id) free_2(v->id);
1591 				if(v->value) free_2(v->value);
1592 				free_2(v);
1593 				GLOBALS->pv_vcd_partial_c_2 = NULL;
1594 				}
1595 
1596 			bail:
1597 			if(vtok!=V_END) sync_end(NULL);
1598 			break;
1599 			}
1600 		case T_ENDDEFINITIONS:
1601 			GLOBALS->header_over_vcd_partial_c_2=1;	/* do symbol table management here */
1602 			create_sorted_table();
1603 			if((!GLOBALS->sorted_vcd_partial_c_2)&&(!GLOBALS->indexed_vcd_partial_c_2))
1604 				{
1605 				fprintf(stderr, "No symbols in VCD file..nothing to do!\n");
1606 				exit(1);
1607 				}
1608 			if(GLOBALS->error_count_vcd_partial_c_2)
1609 				{
1610 				fprintf(stderr, "\n%d VCD parse errors encountered, exiting.\n", GLOBALS->error_count_vcd_partial_c_2);
1611 				exit(1);
1612 				}
1613 			return;
1614 			break;
1615 		case T_STRING:
1616 			if(!GLOBALS->header_over_vcd_partial_c_2)
1617 				{
1618 				GLOBALS->header_over_vcd_partial_c_2=1;	/* do symbol table management here */
1619 				create_sorted_table();
1620 				if((!GLOBALS->sorted_vcd_partial_c_2)&&(!GLOBALS->indexed_vcd_partial_c_2)) break;
1621 				}
1622 				{
1623 				/* catchall for events when header over */
1624 				if(GLOBALS->yytext_vcd_partial_c_2[0]=='#')
1625 					{
1626 					TimeType tim;
1627 					tim=atoi_64(GLOBALS->yytext_vcd_partial_c_2+1);
1628 
1629 					if(GLOBALS->start_time_vcd_partial_c_2<0)
1630 						{
1631 						GLOBALS->start_time_vcd_partial_c_2=tim;
1632 						}
1633 
1634 					GLOBALS->current_time_vcd_partial_c_2=tim;
1635 					if(GLOBALS->end_time_vcd_partial_c_2<tim) GLOBALS->end_time_vcd_partial_c_2=tim;	/* in case of malformed vcd files */
1636 					DEBUG(fprintf(stderr,"#"TTFormat"\n",tim));
1637 					}
1638 					else
1639 					{
1640 					parse_valuechange();
1641 					}
1642 				}
1643 			break;
1644 		case T_DUMPALL:	/* dump commands modify vals anyway so */
1645 		case T_DUMPPORTSALL:
1646 			break;	/* just loop through..                 */
1647 		case T_DUMPOFF:
1648 		case T_DUMPPORTSOFF:
1649 			GLOBALS->dumping_off_vcd_partial_c_2=1;
1650                         /* if((!GLOBALS->blackout_regions)||((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart<=GLOBALS->blackout_regions->bend))) : remove redundant condition */
1651                         if((!GLOBALS->blackout_regions)||(GLOBALS->blackout_regions->bstart<=GLOBALS->blackout_regions->bend))
1652 				{
1653 				struct blackout_region_t *bt = calloc_2(1, sizeof(struct blackout_region_t));
1654 
1655 				bt->bstart = GLOBALS->current_time_vcd_partial_c_2 * GLOBALS->time_scale;
1656 				bt->next = GLOBALS->blackout_regions;
1657 				GLOBALS->blackout_regions = bt;
1658 				}
1659 			break;
1660 		case T_DUMPON:
1661 		case T_DUMPPORTSON:
1662 			GLOBALS->dumping_off_vcd_partial_c_2=0;
1663 			if((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart>GLOBALS->blackout_regions->bend))
1664 				{
1665 				GLOBALS->blackout_regions->bend = GLOBALS->current_time_vcd_partial_c_2 * GLOBALS->time_scale;
1666 				}
1667 			break;
1668 		case T_DUMPVARS:
1669 		case T_DUMPPORTS:
1670 			if(GLOBALS->current_time_vcd_partial_c_2<0)
1671 				{ GLOBALS->start_time_vcd_partial_c_2=GLOBALS->current_time_vcd_partial_c_2=GLOBALS->end_time_vcd_partial_c_2=0; }
1672 			break;
1673 		case T_VCDCLOSE:
1674 			sync_end("VCDCLOSE:");
1675 			break;	/* next token will be '#' time related followed by $end */
1676 		case T_END:	/* either closure for dump commands or */
1677 			break;	/* it's spurious                       */
1678 		case T_UNKNOWN_KEY:
1679 			sync_end(NULL);	/* skip over unknown keywords */
1680 			break;
1681 		case T_EOF:
1682 			if((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart>GLOBALS->blackout_regions->bend))
1683 				{
1684 				GLOBALS->blackout_regions->bend = GLOBALS->current_time_vcd_partial_c_2 * GLOBALS->time_scale;
1685 				}
1686 			return;
1687 		default:
1688 			DEBUG(fprintf(stderr,"UNKNOWN TOKEN\n"));
1689 		}
1690 	}
1691 }
1692 
1693 
1694 /*******************************************************************************/
1695 
add_histent_p(TimeType tim,struct Node * n,char ch,int regadd,char * vector)1696 hptr add_histent_p(TimeType tim, struct Node *n, char ch, int regadd, char *vector)
1697 {
1698 struct HistEnt *he, *rc;
1699 char heval;
1700 
1701 if(!vector)
1702 {
1703 if(!(rc=n->curr))
1704 	{
1705 	he=histent_calloc();
1706         he->time=-1;
1707         he->v.h_val=AN_X;
1708 
1709 	n->curr=he;
1710 	n->head.next=he;
1711 
1712 	add_histent_p(tim,n,ch,regadd, vector);
1713 	rc = he;
1714 	}
1715 	else
1716 	{
1717 	if(regadd) { tim*=(GLOBALS->time_scale); }
1718 
1719 	if(ch=='0')              heval=AN_0; else
1720 	if(ch=='1')              heval=AN_1; else
1721         if((ch=='x')||(ch=='X')) heval=AN_X; else
1722         if((ch=='z')||(ch=='Z')) heval=AN_Z; else
1723         if((ch=='h')||(ch=='H')) heval=AN_H; else
1724         if((ch=='u')||(ch=='U')) heval=AN_U; else
1725         if((ch=='w')||(ch=='W')) heval=AN_W; else
1726         if((ch=='l')||(ch=='L')) heval=AN_L; else
1727         /* if(ch=='-') */        heval=AN_DASH;		/* default */
1728 
1729 	if((n->curr->v.h_val!=heval)||(tim==GLOBALS->start_time_vcd_partial_c_2)||(n->vartype==ND_VCD_EVENT)||(GLOBALS->vcd_preserve_glitches)) /* same region == go skip */
1730         	{
1731 		if(n->curr->time==tim)
1732 			{
1733 			DEBUG(printf("Warning: Glitch at time ["TTFormat"] Signal [%p], Value [%c->%c].\n",
1734 				tim, n, AN_STR[n->curr->v.h_val], ch));
1735 			n->curr->v.h_val=heval;		/* we have a glitch! */
1736 
1737 			GLOBALS->num_glitches_vcd_partial_c_3++;
1738 			if(!(n->curr->flags&HIST_GLITCH))
1739 				{
1740 				n->curr->flags|=HIST_GLITCH;	/* set the glitch flag */
1741 				GLOBALS->num_glitch_regions_vcd_partial_c_3++;
1742 				}
1743 			}
1744 			else
1745 			{
1746                 	he=histent_calloc();
1747                 	he->time=tim;
1748                 	he->v.h_val=heval;
1749 
1750                 	n->curr->next=he;
1751                         if(n->curr->v.h_val==heval)
1752                                 {
1753                                 n->curr->flags|=HIST_GLITCH;    /* set the glitch flag */
1754                                 GLOBALS->num_glitch_regions_vcd_recoder_c_4++;
1755                                 }
1756 			n->curr=he;
1757                 	GLOBALS->regions+=regadd;
1758 			}
1759                 }
1760        }
1761 }
1762 else
1763 {
1764 switch(ch)
1765 	{
1766 	case 's': /* string */
1767 	{
1768 	if(!(rc=n->curr))
1769 		{
1770 		he=histent_calloc();
1771 		he->flags=(HIST_STRING|HIST_REAL);
1772 	        he->time=-1;
1773 	        he->v.h_vector=NULL;
1774 
1775 		n->curr=he;
1776 		n->head.next=he;
1777 
1778 		add_histent_p(tim,n,ch,regadd, vector);
1779 		rc = he;
1780 		}
1781 		else
1782 		{
1783 		if(regadd) { tim*=(GLOBALS->time_scale); }
1784 
1785 			if(n->curr->time==tim)
1786 				{
1787 				DEBUG(printf("Warning: String Glitch at time ["TTFormat"] Signal [%p].\n",
1788 					tim, n));
1789 				if(n->curr->v.h_vector) free_2(n->curr->v.h_vector);
1790 				n->curr->v.h_vector=vector;		/* we have a glitch! */
1791 
1792 				GLOBALS->num_glitches_vcd_partial_c_3++;
1793 				if(!(n->curr->flags&HIST_GLITCH))
1794 					{
1795 					n->curr->flags|=HIST_GLITCH;	/* set the glitch flag */
1796 					GLOBALS->num_glitch_regions_vcd_partial_c_3++;
1797 					}
1798 				}
1799 				else
1800 				{
1801 	                	he=histent_calloc();
1802 				he->flags=(HIST_STRING|HIST_REAL);
1803 	                	he->time=tim;
1804 	                	he->v.h_vector=vector;
1805 
1806 	                	n->curr->next=he;
1807 				n->curr=he;
1808 	                	GLOBALS->regions+=regadd;
1809 				}
1810 	       }
1811 	break;
1812 	}
1813 	case 'g': /* real number */
1814 	{
1815 	if(!(rc=n->curr))
1816 		{
1817 		he=histent_calloc();
1818 		he->flags=HIST_REAL;
1819 	        he->time=-1;
1820 #ifdef WAVE_HAS_H_DOUBLE
1821                 he->v.h_double = strtod("NaN", NULL);
1822 #else
1823 	        he->v.h_vector=NULL;
1824 #endif
1825 		n->curr=he;
1826 		n->head.next=he;
1827 
1828 		add_histent_p(tim,n,ch,regadd, vector);
1829 		rc = he;
1830 		}
1831 		else
1832 		{
1833 		if(regadd) { tim*=(GLOBALS->time_scale); }
1834 
1835 		if(
1836 #ifdef WAVE_HAS_H_DOUBLE
1837                   (vector&&(n->curr->v.h_double!=*(double *)vector))
1838 #else
1839 		  (n->curr->v.h_vector&&vector&&(*(double *)n->curr->v.h_vector!=*(double *)vector))
1840 #endif
1841 			||(tim==GLOBALS->start_time_vcd_partial_c_2)
1842 #ifndef WAVE_HAS_H_DOUBLE
1843 			||(!n->curr->v.h_vector)
1844 #endif
1845 			||(GLOBALS->vcd_preserve_glitches)||(GLOBALS->vcd_preserve_glitches_real)
1846 			) /* same region == go skip */
1847 	        	{
1848 			if(n->curr->time==tim)
1849 				{
1850 				DEBUG(printf("Warning: Real number Glitch at time ["TTFormat"] Signal [%p].\n",
1851 					tim, n));
1852 #ifdef WAVE_HAS_H_DOUBLE
1853                                 n->curr->v.h_double = *((double *)vector);
1854 #else
1855 				if(n->curr->v.h_vector) free_2(n->curr->v.h_vector);
1856 				n->curr->v.h_vector=vector;		/* we have a glitch! */
1857 #endif
1858 				GLOBALS->num_glitches_vcd_partial_c_3++;
1859 				if(!(n->curr->flags&HIST_GLITCH))
1860 					{
1861 					n->curr->flags|=HIST_GLITCH;	/* set the glitch flag */
1862 					GLOBALS->num_glitch_regions_vcd_partial_c_3++;
1863 					}
1864 				}
1865 				else
1866 				{
1867 	                	he=histent_calloc();
1868 				he->flags=HIST_REAL;
1869 	                	he->time=tim;
1870 #ifdef WAVE_HAS_H_DOUBLE
1871                                 he->v.h_double = *((double *)vector);
1872 #else
1873 	                	he->v.h_vector=vector;
1874 #endif
1875 	                	n->curr->next=he;
1876 				n->curr=he;
1877 	                	GLOBALS->regions+=regadd;
1878 				}
1879 	                }
1880 			else
1881 			{
1882 #ifndef WAVE_HAS_H_DOUBLE
1883 			free_2(vector);
1884 #endif
1885 			}
1886 #ifdef WAVE_HAS_H_DOUBLE
1887 	        free_2(vector);
1888 #endif
1889 	       }
1890 	break;
1891 	}
1892 	default:
1893 	{
1894 	if(!(rc=n->curr))
1895 		{
1896 		he=histent_calloc();
1897 	        he->time=-1;
1898 	        he->v.h_vector=NULL;
1899 
1900 		n->curr=he;
1901 		n->head.next=he;
1902 
1903 		add_histent_p(tim,n,ch,regadd, vector);
1904 		rc = he;
1905 		}
1906 		else
1907 		{
1908 		if(regadd) { tim*=(GLOBALS->time_scale); }
1909 
1910 		if(
1911 		  (n->curr->v.h_vector&&vector&&(strcmp(n->curr->v.h_vector,vector)))
1912 			||(tim==GLOBALS->start_time_vcd_partial_c_2)
1913 			||(!n->curr->v.h_vector)
1914 			||(GLOBALS->vcd_preserve_glitches)
1915 			) /* same region == go skip */
1916 	        	{
1917 			if(n->curr->time==tim)
1918 				{
1919 				DEBUG(printf("Warning: Glitch at time ["TTFormat"] Signal [%p], Value [%c->%c].\n",
1920 					tim, n, AN_STR[n->curr->v.h_val], ch));
1921 				if(n->curr->v.h_vector) free_2(n->curr->v.h_vector);
1922 				n->curr->v.h_vector=vector;		/* we have a glitch! */
1923 
1924 				GLOBALS->num_glitches_vcd_partial_c_3++;
1925 				if(!(n->curr->flags&HIST_GLITCH))
1926 					{
1927 					n->curr->flags|=HIST_GLITCH;	/* set the glitch flag */
1928 					GLOBALS->num_glitch_regions_vcd_partial_c_3++;
1929 					}
1930 				}
1931 				else
1932 				{
1933 	                	he=histent_calloc();
1934 	                	he->time=tim;
1935 	                	he->v.h_vector=vector;
1936 
1937 	                	n->curr->next=he;
1938 				n->curr=he;
1939 	                	GLOBALS->regions+=regadd;
1940 				}
1941 	                }
1942 			else
1943 			{
1944 			free_2(vector);
1945 			}
1946 	       }
1947 	break;
1948 	}
1949 	}
1950 }
1951 
1952 return(rc);
1953 }
1954 
1955 
add_tail_histents(void)1956 static void add_tail_histents(void)
1957 {
1958 int j;
1959 struct vcdsymbol *v;
1960 hptr rc;
1961 
1962 
1963 /* do 'x' trailers */
1964 
1965 v=GLOBALS->vcdsymroot_vcd_partial_c_2;
1966 while(v)
1967 	{
1968 	if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE))
1969 		{
1970 		double *d;
1971 
1972 		d=malloc_2(sizeof(double));
1973 		*d=1.0;
1974 		rc = add_histent_p(MAX_HISTENT_TIME-1, v->narray[0], 'g', 0, (char *)d);
1975 		set_vcd_vartype(v, v->narray[0]);
1976 		v->app_array[0] = rc;
1977 		v->tr_array[0] = v->narray[0]->curr;
1978 		}
1979 	else
1980 	if((v->size==1)||(!GLOBALS->atomic_vectors))
1981 	for(j=0;j<v->size;j++)
1982 		{
1983 		rc = add_histent_p(MAX_HISTENT_TIME-1, v->narray[j], 'x', 0, NULL);
1984 		set_vcd_vartype(v, v->narray[j]);
1985 		v->app_array[j] = rc;
1986 		v->tr_array[j] = v->narray[j]->curr;
1987 		}
1988 	else
1989 		{
1990 		rc = add_histent_p(MAX_HISTENT_TIME-1, v->narray[0], 'x', 0, (char *)calloc_2(1,sizeof(char)));
1991 		set_vcd_vartype(v, v->narray[0]);
1992 		v->app_array[0] = rc;
1993 		v->tr_array[0] = v->narray[0]->curr;
1994 		}
1995 
1996 	v=v->next;
1997 	}
1998 
1999 v=GLOBALS->vcdsymroot_vcd_partial_c_2;
2000 while(v)
2001 	{
2002 	if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE))
2003 		{
2004 		double *d;
2005 
2006 		d=malloc_2(sizeof(double));
2007 		*d=0.0;
2008 		add_histent_p(MAX_HISTENT_TIME, v->narray[0], 'g', 0, (char *)d);
2009 		}
2010 	else
2011 	if((v->size==1)||(!GLOBALS->atomic_vectors))
2012 	for(j=0;j<v->size;j++)
2013 		{
2014 		add_histent_p(MAX_HISTENT_TIME, v->narray[j], 'z', 0, NULL);
2015 		}
2016 	else
2017 		{
2018 		add_histent_p(MAX_HISTENT_TIME, v->narray[0], 'z', 0, (char *)calloc_2(1,sizeof(char)));
2019 		}
2020 
2021 	v=v->next;
2022 	}
2023 }
2024 
2025 /*******************************************************************************/
2026 
vcd_build_symbols(void)2027 static void vcd_build_symbols(void)
2028 {
2029 int j;
2030 int max_slen=-1;
2031 struct sym_chain *sym_chain=NULL, *sym_curr=NULL;
2032 int duphier=0;
2033 char hashdirty;
2034 struct vcdsymbol *v, *vprime;
2035 char *str = wave_alloca(1); /* quiet scan-build null pointer warning below */
2036 #ifdef _WAVE_HAVE_JUDY
2037 int ss_len, longest = 0;
2038 #endif
2039 
2040 v=GLOBALS->vcdsymroot_vcd_partial_c_2;
2041 while(v)
2042 	{
2043 	int msi;
2044 	int delta;
2045 
2046 		{
2047 		int slen;
2048 		int substnode;
2049 
2050 		msi=v->msi;
2051 		delta=((v->lsi-v->msi)<0)?-1:1;
2052 		substnode=0;
2053 
2054 		slen=strlen(v->name);
2055 		str=(slen>max_slen)?(wave_alloca((max_slen=slen)+32)):(str); /* more than enough */
2056 		strcpy(str,v->name);
2057 
2058 		if((v->msi>=0)||(v->msi != v->lsi))
2059 			{
2060 			strcpy(str+slen,GLOBALS->vcd_hier_delimeter);
2061 			slen++;
2062 			}
2063 
2064 		if((vprime=bsearch_vcd(v->id, strlen(v->id)))!=v) /* hash mish means dup net */
2065 			{
2066 			if(v->size!=vprime->size)
2067 				{
2068 				fprintf(stderr,"ERROR: Duplicate IDs with differing width: %s %s\n", v->name, vprime->name);
2069 				}
2070 				else
2071 				{
2072 				substnode=1;
2073 				}
2074 			}
2075 
2076 		if(((v->size==1)||(!GLOBALS->atomic_vectors))&&(v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE))
2077 			{
2078 			struct symbol *s = NULL;
2079 
2080 			for(j=0;j<v->size;j++)
2081 				{
2082 				if(v->msi>=0)
2083 					{
2084 					if(!GLOBALS->vcd_explicit_zero_subscripts)
2085 						sprintf(str+slen,"%d",msi);
2086 						else
2087 						sprintf(str+slen-1,"[%d]",msi);
2088 					}
2089 
2090 				hashdirty=0;
2091 				if(symfind(str, NULL))
2092 					{
2093 					char *dupfix=(char *)malloc_2(max_slen+32);
2094 #ifndef _WAVE_HAVE_JUDY
2095 					hashdirty=1;
2096 #endif
2097 					DEBUG(fprintf(stderr,"Warning: %s is a duplicate net name.\n",str));
2098 
2099 					do sprintf(dupfix, "$DUP%d%s%s", duphier++, GLOBALS->vcd_hier_delimeter, str);
2100 						while(symfind(dupfix, NULL));
2101 
2102 					strcpy(str, dupfix);
2103 					free_2(dupfix);
2104 					duphier=0; /* reset for next duplicate resolution */
2105 					}
2106 					/* fallthrough */
2107 					{
2108 					s=symadd(str,hashdirty?hash(str):GLOBALS->hashcache);
2109 #ifdef _WAVE_HAVE_JUDY
2110                                         ss_len = strlen(str); if(ss_len >= longest) { longest = ss_len + 1; }
2111 #endif
2112 					s->n=v->narray[j];
2113 					if(substnode)
2114 						{
2115 						struct Node *n, *n2;
2116 
2117 						n=s->n;
2118 						n2=vprime->narray[j];
2119 						/* nname stays same */
2120 						n->head=n2->head;
2121 						n->curr=n2->curr;
2122 						/* harray calculated later */
2123 						n->numhist=n2->numhist;
2124 						}
2125 
2126 #ifndef _WAVE_HAVE_JUDY
2127 					s->n->nname=s->name;
2128 #endif
2129 					if(!GLOBALS->firstnode)
2130 					        {
2131 					        GLOBALS->firstnode=
2132 					        GLOBALS->curnode=calloc_2(1, sizeof(struct symchain));
2133 					        }
2134 					        else
2135 					        {
2136 					        GLOBALS->curnode->next=calloc_2(1, sizeof(struct symchain));
2137 					        GLOBALS->curnode=GLOBALS->curnode->next;
2138 					        }
2139 					GLOBALS->curnode->symbol=s;
2140 
2141 					GLOBALS->numfacs++;
2142 					DEBUG(fprintf(stderr,"Added: %s\n",str));
2143 					}
2144 				msi+=delta;
2145 				}
2146 
2147 			if((j==1)&&(v->root))
2148 				{
2149 				s->vec_root=(struct symbol *)v->root;		/* these will get patched over */
2150 				s->vec_chain=(struct symbol *)v->chain;		/* these will get patched over */
2151 				v->sym_chain=s;
2152 
2153 				if(!sym_chain)
2154 					{
2155 					sym_curr=(struct sym_chain *)calloc_2(1,sizeof(struct sym_chain));
2156 					sym_chain=sym_curr;
2157 					}
2158 					else
2159 					{
2160 					sym_curr->next=(struct sym_chain *)calloc_2(1,sizeof(struct sym_chain));
2161 					sym_curr=sym_curr->next;
2162 					}
2163 				sym_curr->val=s;
2164 				}
2165 			}
2166 			else	/* atomic vector */
2167 			{
2168 			if((v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE)&&(v->vartype!=V_INTEGER)&&(v->vartype!=V_PARAMETER))
2169 			/* if((v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE)) */
2170 				{
2171 				sprintf(str+slen-1,"[%d:%d]",v->msi,v->lsi);
2172 				/* 2d add */
2173                                 if((v->msi>v->lsi)&&((v->msi-v->lsi+1)!=v->size))
2174                                         {
2175                                         if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER))
2176                                                 {
2177                                                 v->msi = v->size-1; v->lsi = 0;
2178                                                 }
2179                                         }
2180                                 else
2181                                 if((v->lsi>=v->msi)&&((v->lsi-v->msi+1)!=v->size))
2182                                         {
2183                                         if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER))
2184                                                 {
2185                                                 v->lsi = v->size-1; v->msi = 0;
2186                                                 }
2187                                         }
2188 				}
2189 				else
2190 				{
2191 				*(str+slen-1)=0;
2192 				}
2193 
2194 
2195 			hashdirty=0;
2196 			if(symfind(str, NULL))
2197 				{
2198 				char *dupfix=(char *)malloc_2(max_slen+32);
2199 #ifndef _WAVE_HAVE_JUDY
2200 				hashdirty=1;
2201 #endif
2202 				DEBUG(fprintf(stderr,"Warning: %s is a duplicate net name.\n",str));
2203 
2204 				do sprintf(dupfix, "$DUP%d%s%s", duphier++, GLOBALS->vcd_hier_delimeter, str);
2205 					while(symfind(dupfix, NULL));
2206 
2207 				strcpy(str, dupfix);
2208 				free_2(dupfix);
2209 				duphier=0; /* reset for next duplicate resolution */
2210 				}
2211 				/* fallthrough */
2212 				{
2213 				struct symbol *s;
2214 
2215 				s=symadd(str,hashdirty?hash(str):GLOBALS->hashcache);	/* cut down on double lookups.. */
2216 #ifdef _WAVE_HAVE_JUDY
2217                                 ss_len = strlen(str); if(ss_len >= longest) { longest = ss_len + 1; }
2218 #endif
2219 				s->n=v->narray[0];
2220 				if(substnode)
2221 					{
2222 					struct Node *n, *n2;
2223 
2224 					n=s->n;
2225 					n2=vprime->narray[0];
2226 					/* nname stays same */
2227 					n->head=n2->head;
2228 					n->curr=n2->curr;
2229 					/* harray calculated later */
2230 					n->numhist=n2->numhist;
2231 					n->extvals=n2->extvals;
2232 					n->msi=n2->msi;
2233 					n->lsi=n2->lsi;
2234 					}
2235 					else
2236 					{
2237 					s->n->msi=v->msi;
2238 					s->n->lsi=v->lsi;
2239 
2240 					s->n->extvals=1;
2241 					}
2242 
2243 #ifndef _WAVE_HAVE_JUDY
2244 				s->n->nname=s->name;
2245 #endif
2246 				if(!GLOBALS->firstnode)
2247 				        {
2248 				        GLOBALS->firstnode=
2249 				        GLOBALS->curnode=calloc_2(1, sizeof(struct symchain));
2250 				        }
2251 				        else
2252 				        {
2253 				        GLOBALS->curnode->next=calloc_2(1, sizeof(struct symchain));
2254 				        GLOBALS->curnode=GLOBALS->curnode->next;
2255 				        }
2256 				GLOBALS->curnode->symbol=s;
2257 
2258 				GLOBALS->numfacs++;
2259 				DEBUG(fprintf(stderr,"Added: %s\n",str));
2260 				}
2261 			}
2262 		}
2263 
2264 	v=v->next;
2265 	}
2266 
2267 #ifdef _WAVE_HAVE_JUDY
2268 {
2269 Pvoid_t  PJArray = GLOBALS->sym_judy;
2270 PPvoid_t PPValue;
2271 char *Index = calloc_2(1, longest);
2272 
2273 for (PPValue  = JudySLFirst (PJArray, (uint8_t *)Index, PJE0);
2274          PPValue != (PPvoid_t) NULL;
2275          PPValue  = JudySLNext  (PJArray, (uint8_t *)Index, PJE0))
2276     {
2277         struct symbol *s = *(struct symbol **)PPValue;
2278         s->name = strdup_2(Index);
2279         s->n->nname = s->name;
2280     }
2281 
2282 free_2(Index);
2283 }
2284 #endif
2285 
2286 if(sym_chain)
2287 	{
2288 	sym_curr=sym_chain;
2289 	while(sym_curr)
2290 		{
2291 		sym_curr->val->vec_root= ((struct vcdsymbol *)sym_curr->val->vec_root)->sym_chain;
2292 
2293 		if ((struct vcdsymbol *)sym_curr->val->vec_chain)
2294 			sym_curr->val->vec_chain=((struct vcdsymbol *)sym_curr->val->vec_chain)->sym_chain;
2295 
2296 		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)"));
2297 
2298 		sym_chain=sym_curr;
2299 		sym_curr=sym_curr->next;
2300 		free_2(sym_chain);
2301 		}
2302 	}
2303 }
2304 
2305 /*******************************************************************************/
2306 
vcd_cleanup(void)2307 static void vcd_cleanup(void)
2308 {
2309 struct slist *s, *s2;
2310 
2311 if(GLOBALS->slisthier) { free_2(GLOBALS->slisthier); GLOBALS->slisthier=NULL; }
2312 s=GLOBALS->slistroot;
2313 while(s)
2314 	{
2315 	s2=s->next;
2316 	if(s->str)free_2(s->str);
2317 	free_2(s);
2318 	s=s2;
2319 	}
2320 
2321 GLOBALS->slistroot=GLOBALS->slistcurr=NULL; GLOBALS->slisthier_len=0;
2322 }
2323 
2324 /*******************************************************************************/
2325 
vcd_partial_main(char * fname)2326 TimeType vcd_partial_main(char *fname)
2327 {
2328 unsigned int shmidu = ~(0L);
2329 int shmid;
2330 
2331 GLOBALS->pv_vcd_partial_c_2=GLOBALS->rootv_vcd_partial_c_2=NULL;
2332 GLOBALS->vcd_hier_delimeter[0]=GLOBALS->hier_delimeter;
2333 
2334 errno=0;	/* reset in case it's set for some reason */
2335 
2336 GLOBALS->yytext_vcd_partial_c_2=(char *)malloc_2(GLOBALS->T_MAX_STR_vcd_partial_c_2+1);
2337 
2338 if(!GLOBALS->hier_was_explicitly_set) /* set default hierarchy split char */
2339 	{
2340 	GLOBALS->hier_delimeter='.';
2341 	}
2342 
2343 #ifdef __MINGW32__
2344 if(GetEnvironmentVariable("SHMID", NULL, 0))
2345  	{
2346 	char sEnv[128];
2347 	GetEnvironmentVariable("SHMID", sEnv, 128);
2348   	sscanf(sEnv, "%x", &shmidu);
2349  	}
2350 else
2351 #endif
2352 	{
2353 	if(!strcmp(fname, "-vcd"))
2354 		{
2355 		if(!fscanf(stdin, "%x", &shmidu)) shmidu = ~(0L); /* allow use of -v flag to pass straight from stdin */
2356 		}
2357 		else
2358 		{
2359 		sscanf(fname, "%x", &shmidu);	/* passed as a filename */
2360 		}
2361 	}
2362 
2363 shmid = (int)shmidu;
2364 
2365 #if !defined _MSC_VER
2366 #ifdef __MINGW32__
2367 {
2368 HANDLE hMapFile;
2369 char mapName[257];
2370 
2371 sprintf(mapName, "shmidcat%d", shmid);
2372 hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, mapName);
2373 if(hMapFile == NULL)
2374 	{
2375 	fprintf(stderr, "Could not attach shared memory map name '%s', exiting.\n", mapName);
2376 	exit(255);
2377 	}
2378 GLOBALS->consume_ptr_vcd_partial_c_1 = GLOBALS->buf_vcd_partial_c_2 = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, WAVE_PARTIAL_VCD_RING_BUFFER_SIZE);
2379 if(GLOBALS->consume_ptr_vcd_partial_c_1 == NULL)
2380 	{
2381 	fprintf(stderr, "Could not map view of file '%s', exiting.\n", mapName);
2382 	exit(255);
2383 	}
2384 }
2385 #else
2386 errno = 0;
2387 GLOBALS->consume_ptr_vcd_partial_c_1 = GLOBALS->buf_vcd_partial_c_2 = shmat(shmid, NULL, 0);
2388 if(errno)
2389 	{
2390 	fprintf(stderr, "Could not attach shared memory ID %08x\n", shmid);
2391 	perror("Why");
2392 	exit(255);
2393 	}
2394 #endif
2395 #else
2396 fprintf(stderr, "Interactive VCD mode does not work with Windows, exiting.\n");
2397 exit(255);
2398 #endif
2399 
2400 sym_hash_initialize(GLOBALS);
2401 getch_alloc();		/* alloc membuff for vcd getch buffer */
2402 build_slisthier();
2403 
2404 GLOBALS->vcd_preserve_glitches = 1; /* splicing dictates that we override */
2405 while(!GLOBALS->header_over_vcd_partial_c_2) { vcd_parse(); }
2406 
2407 if(GLOBALS->varsplit_vcd_partial_c_2)
2408 	{
2409 	free_2(GLOBALS->varsplit_vcd_partial_c_2);
2410 	GLOBALS->varsplit_vcd_partial_c_2=NULL;
2411 	}
2412 
2413 if((!GLOBALS->sorted_vcd_partial_c_2)&&(!GLOBALS->indexed_vcd_partial_c_2))
2414 	{
2415 	fprintf(stderr, "No symbols in VCD file..is it malformed?  Exiting!\n");
2416 	exit(1);
2417 	}
2418 
2419 add_tail_histents();
2420 vcd_build_symbols();
2421 vcd_sortfacs();
2422 vcd_cleanup();
2423 
2424 GLOBALS->min_time=GLOBALS->start_time_vcd_partial_c_2*GLOBALS->time_scale;
2425 GLOBALS->max_time=GLOBALS->end_time_vcd_partial_c_2*GLOBALS->time_scale;
2426 GLOBALS->global_time_offset = GLOBALS->global_time_offset * GLOBALS->time_scale;
2427 
2428 if((GLOBALS->min_time==GLOBALS->max_time)||(GLOBALS->max_time==0))
2429         {
2430 	GLOBALS->min_time = GLOBALS->max_time = 0;
2431         }
2432 
2433 GLOBALS->is_vcd=~0;
2434 GLOBALS->partial_vcd = ~0;
2435 
2436 #ifdef __linux__
2437 	{
2438 	struct shmid_ds ds;
2439 	shmctl(shmid, IPC_RMID, &ds); /* mark for destroy */
2440 	}
2441 #endif
2442 
2443 return(GLOBALS->max_time);
2444 }
2445 
2446 /*******************************************************************************/
2447 
regen_harray(Trptr t,nptr nd)2448 static void regen_harray(Trptr t, nptr nd)
2449 {
2450 int i, histcount;
2451 hptr histpnt;
2452 hptr *harray;
2453 
2454 if(!nd->harray)         /* make quick array lookup for aet display */
2455         {
2456         histpnt=&(nd->head);
2457         histcount=0;
2458 
2459         while(histpnt)
2460                 {
2461                 histcount++;
2462                 histpnt=histpnt->next;
2463                 }
2464 
2465         nd->numhist=histcount;
2466 
2467         if(!(nd->harray=harray=(hptr *)malloc_2(histcount*sizeof(hptr))))
2468                 {
2469                 fprintf( stderr, "Out of memory, can't add %s to analyzer\n",
2470                         nd->nname );
2471                 free_2(t);
2472 		return; /* scan-build : really can't do anything here */
2473                 }
2474 
2475         histpnt=&(nd->head);
2476         for(i=0;i<histcount;i++)
2477                 {
2478                 *harray=histpnt;
2479 
2480                 /* printf("%s, time: %d, val: %d\n", nd->nname,
2481                         (*harray)->time, (*harray)->val); */
2482 
2483                 harray++;
2484                 histpnt=histpnt->next;
2485                 }
2486         }
2487 }
2488 
2489 /* mark vectors that need to be regenerated */
regen_trace_mark(Trptr t,int mandclear)2490 static void regen_trace_mark(Trptr t, int mandclear)
2491 {
2492 if(t->vector)
2493 	{
2494 	bvptr b = t->n.vec;
2495 	bptr bts = b->bits;
2496 	int i;
2497 
2498 	if(1)
2499 		{
2500 		for(i=0;i<bts->nnbits;i++)
2501 			{
2502 			if(!bts->nodes[i]->expansion)
2503 				{
2504 				if(bts->nodes[i]->harray)
2505 					{
2506 					free_2(bts->nodes[i]->harray);
2507 					bts->nodes[i]->harray = NULL;
2508 					}
2509 				}
2510 				else
2511 				{
2512 				t->interactive_vector_needs_regeneration = 1;
2513 				}
2514 			}
2515 		}
2516 
2517 	for(i=0;i<bts->nnbits;i++)
2518 		{
2519 		if(!bts->nodes[i]->harray)
2520 			{
2521 			t->interactive_vector_needs_regeneration = 1;
2522 			return;
2523 			}
2524 		}
2525 	}
2526 	else
2527 	{
2528 	if(t->n.nd) /* comment and blank traces don't have a valid node */
2529 	if((t->n.nd->harray) && (mandclear))
2530 		{
2531 		free_2(t->n.nd->harray);
2532 		t->n.nd->harray = NULL;
2533 		}
2534 	}
2535 }
2536 
2537 /* sweep through and regen nodes/dirty vectors */
regen_trace_sweep(Trptr t)2538 static void regen_trace_sweep(Trptr t)
2539 {
2540 if(!t->vector)
2541 	{
2542 	if(t->n.nd) /* comment and blank traces don't have a valid node */
2543 	if(!t->n.nd->harray)
2544 		{
2545 		regen_harray(t, t->n.nd);
2546 		}
2547 	}
2548 else if(t->interactive_vector_needs_regeneration)
2549 	{
2550 	bvptr b = t->n.vec;
2551 	bptr bts = b->bits;
2552 	int i;
2553 	bvptr b2;
2554 
2555 	for(i=0;i<bts->nnbits;i++)
2556 		{
2557 		if(bts->nodes[i]->expansion)
2558 			{
2559 			nptr parent = bts->nodes[i]->expansion->parent;
2560 			int parentbit = bts->nodes[i]->expansion->parentbit;
2561 
2562 			DeleteNode(bts->nodes[i]);
2563 
2564 			bts->nodes[i] = ExtractNodeSingleBit(parent, parentbit);
2565 			}
2566 
2567 		if(!bts->nodes[i]->harray)
2568 			{
2569 			regen_harray(t, bts->nodes[i]);
2570 			}
2571 		}
2572 
2573 	if(!bts->name)
2574 		{
2575 		bts->name = "";
2576 		b2 = bits2vector(bts);
2577 		bts->name = NULL;
2578 		}
2579 		else
2580 		{
2581 		b2 = bits2vector(bts);
2582 		}
2583 
2584 	t->n.vec = b2;
2585 	b2->bits=bts;
2586 
2587 	free_2(b2->bvname);
2588 	b2->bvname = b->bvname;
2589 
2590 	for(i=0;i<b->numregions;i++)
2591 		{
2592 		free_2(b->vectors[i]);
2593 		}
2594 
2595 	free_2(b);
2596 	}
2597 }
2598 
2599 /*******************************************************************************/
2600 
kick_partial_vcd(void)2601 void kick_partial_vcd(void)
2602 {
2603 #if !defined _MSC_VER
2604 
2605 if(GLOBALS->partial_vcd)
2606 	{
2607 #ifdef __MINGW32__
2608 	Sleep(10);
2609 #else
2610 	struct timeval tv;
2611 
2612 	tv.tv_sec = 0;
2613 	tv.tv_usec = 1000000 / 100;
2614 	select(0, NULL, NULL, NULL, &tv);
2615 #endif
2616 
2617 	while(*GLOBALS->consume_ptr_vcd_partial_c_1)
2618 		{
2619 		int old_maxtime_marker_conflict = (GLOBALS->tims.marker > GLOBALS->max_time);
2620 
2621 		vcd_parse();
2622 
2623 		GLOBALS->min_time=GLOBALS->start_time_vcd_partial_c_2*GLOBALS->time_scale;
2624 		GLOBALS->max_time=GLOBALS->end_time_vcd_partial_c_2*GLOBALS->time_scale;
2625 
2626 		GLOBALS->tims.last=GLOBALS->max_time;
2627 		GLOBALS->tims.end=GLOBALS->tims.last;             /* until the configure_event of wavearea */
2628 
2629 		if(!GLOBALS->timeset_vcd_partial_c_1)
2630 			{
2631 			GLOBALS->tims.first=GLOBALS->tims.start=GLOBALS->tims.laststart=GLOBALS->min_time;
2632 			GLOBALS->timeset_vcd_partial_c_1 = 1;
2633 			}
2634 
2635 		update_endcap_times_for_partial_vcd();
2636 		update_maxmarker_labels();
2637 
2638 		if(old_maxtime_marker_conflict)
2639 			{
2640 			old_maxtime_marker_conflict = (GLOBALS->tims.marker<=GLOBALS->max_time); /* data is now past what was invisible marker */
2641 			}
2642 
2643 		vcd_partial_mark_and_sweep(1);
2644 
2645 		if ((GLOBALS->zoom_dyn) && (!GLOBALS->helpbox_is_active))
2646 			{
2647 			GLOBALS->tims.marker = GLOBALS->tims.last;
2648 			service_zoom_full(NULL, NULL);
2649 
2650 		        GLOBALS->signalwindow_width_dirty=1;
2651 		        MaxSignalLength();
2652 		        signalarea_configure_event(GLOBALS->signalarea, NULL);
2653 			}
2654 		else if ((GLOBALS->zoom_dyne) && (!GLOBALS->helpbox_is_active))
2655 			{
2656 			GLOBALS->tims.marker = GLOBALS->tims.last;
2657 			service_zoom_right(NULL, NULL);
2658 
2659 		        GLOBALS->signalwindow_width_dirty=1;
2660 		        MaxSignalLength();
2661 		        signalarea_configure_event(GLOBALS->signalarea, NULL);
2662 			}
2663 		else if ((old_maxtime_marker_conflict) && (!GLOBALS->helpbox_is_active))
2664 			{
2665 			GLOBALS->signalwindow_width_dirty=1;
2666 			MaxSignalLength();
2667 			signalarea_configure_event(GLOBALS->signalarea, NULL);
2668 		        wavearea_configure_event(GLOBALS->wavearea, NULL);
2669 			}
2670 			else
2671 			{
2672 		        signalarea_configure_event(GLOBALS->signalarea, NULL);
2673 		        wavearea_configure_event(GLOBALS->wavearea, NULL);
2674 			}
2675 
2676 		update_maxmarker_labels();
2677 
2678 		gtkwave_main_iteration();
2679 		}
2680 	}
2681 
2682 #endif
2683 
2684 gtkwave_main_iteration();
2685 }
2686 
2687 
vcd_partial_regen_node_expansion(Trptr t)2688 static void vcd_partial_regen_node_expansion(Trptr t)
2689 {
2690 if(!t->vector)
2691 	{
2692 	if(t->n.nd && t->n.nd->expansion)
2693 		{
2694 		nptr np_ex = ExtractNodeSingleBit(t->n.nd->expansion->parent, t->n.nd->expansion->parentbit);
2695 
2696 		DeleteNode(t->n.nd);
2697 		t->n.nd = np_ex;
2698 		t->name_full = np_ex->nname;
2699 		t->name = (GLOBALS->hier_max_level) ? hier_extract(t->name_full, GLOBALS->hier_max_level) : t->name_full;
2700 		}
2701 	}
2702 
2703 }
2704 
vcd_partial_mark_and_sweep(int mandclear)2705 void vcd_partial_mark_and_sweep(int mandclear)
2706 {
2707 Trptr t;
2708 
2709 
2710 
2711 /* node */
2712 t = GLOBALS->traces.first; while(t) { if(!t->vector) regen_trace_mark(t, mandclear); t = t->t_next; }
2713 t = GLOBALS->traces.buffer; while(t) { if(!t->vector) regen_trace_mark(t, mandclear); t = t->t_next; }
2714 
2715 t = GLOBALS->traces.first; while(t) { if(!t->vector) regen_trace_sweep(t); t = t->t_next; }
2716 t = GLOBALS->traces.buffer; while(t) { if(!t->vector) regen_trace_sweep(t); t = t->t_next; }
2717 
2718 /* node that is single bit extracted */
2719 t = GLOBALS->traces.first; while(t) { vcd_partial_regen_node_expansion(t); t = t->t_next; }
2720 t = GLOBALS->traces.buffer; while(t) { vcd_partial_regen_node_expansion(t); t = t->t_next; }
2721 
2722 /* vector */
2723 t = GLOBALS->traces.first; while(t) { if(t->vector) regen_trace_mark(t, mandclear); t = t->t_next; }
2724 t = GLOBALS->traces.buffer; while(t) { if(t->vector) regen_trace_mark(t, mandclear); t = t->t_next; }
2725 
2726 t = GLOBALS->traces.first; while(t) { if(t->vector) regen_trace_sweep(t); t = t->t_next; }
2727 t = GLOBALS->traces.buffer; while(t) { if(t->vector) regen_trace_sweep(t); t = t->t_next; }
2728 
2729 /* floating point */
2730 t = GLOBALS->traces.first; while(t) { if(t->minmax_valid) t->minmax_valid = 0; t = t->t_next; }
2731 t = GLOBALS->traces.buffer; while(t) { if(t->minmax_valid) t->minmax_valid = 0; t = t->t_next; }
2732 }
2733