1 /*
2  * Copyright (c) Tony Bybell 2003-2012.
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 #include "globals.h"
11 #include <config.h>
12 #include <stdio.h>
13 #include "lx2.h"
14 
15 #ifndef _MSC_VER
16 #include <unistd.h>
17 #endif
18 
19 #include <fcntl.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include "symbol.h"
23 #include "vcd.h"
24 #include "lxt.h"
25 #include "vzt.h"
26 #include "lxt2_read.h"
27 #include "debug.h"
28 #include "busy.h"
29 #include "hierpack.h"
30 #include "fst.h"
31 
32 /*
33  * mainline
34  */
lx2_main(char * fname,char * skip_start,char * skip_end)35 TimeType lx2_main(char *fname, char *skip_start, char *skip_end)
36 {
37 int i;
38 struct Node *n;
39 struct symbol *s, *prevsymroot=NULL, *prevsym=NULL;
40 signed char scale;
41 unsigned int numalias = 0;
42 struct symbol *sym_block = NULL;
43 struct Node *node_block = NULL;
44 char **f_name = NULL;
45 
46 GLOBALS->lx2_lx2_c_1 = lxt2_rd_init(fname);
47 if(!GLOBALS->lx2_lx2_c_1)
48         {
49 	return(LLDescriptor(0));        /* look at GLOBALS->lx2_lx2_c_1 in caller for success status... */
50         }
51 
52 /* SPLASH */                            splash_create();
53 
54 /* lxt2_rd_set_max_block_mem_usage(lx2, 0); */
55 
56 scale=(signed char)lxt2_rd_get_timescale(GLOBALS->lx2_lx2_c_1);
57 exponent_to_time_scale(scale);
58 GLOBALS->global_time_offset = lxt2_rd_get_timezero(GLOBALS->lx2_lx2_c_1);
59 
60 GLOBALS->numfacs=lxt2_rd_get_num_facs(GLOBALS->lx2_lx2_c_1);
61 GLOBALS->mvlfacs_lx2_c_1=(struct fac *)calloc_2(GLOBALS->numfacs,sizeof(struct fac));
62 f_name = calloc_2(F_NAME_MODULUS+1,sizeof(char *));
63 GLOBALS->lx2_table_lx2_c_1=(struct lx2_entry *)calloc_2(GLOBALS->numfacs, sizeof(struct lx2_entry));
64 sym_block = (struct symbol *)calloc_2(GLOBALS->numfacs, sizeof(struct symbol));
65 node_block=(struct Node *)calloc_2(GLOBALS->numfacs,sizeof(struct Node));
66 
67 for(i=0;i<GLOBALS->numfacs;i++)
68 	{
69 	GLOBALS->mvlfacs_lx2_c_1[i].node_alias=lxt2_rd_get_fac_rows(GLOBALS->lx2_lx2_c_1, i);
70 	node_block[i].msi=lxt2_rd_get_fac_msb(GLOBALS->lx2_lx2_c_1, i);
71 	node_block[i].lsi=lxt2_rd_get_fac_lsb(GLOBALS->lx2_lx2_c_1, i);
72 	GLOBALS->mvlfacs_lx2_c_1[i].flags=lxt2_rd_get_fac_flags(GLOBALS->lx2_lx2_c_1, i);
73 	GLOBALS->mvlfacs_lx2_c_1[i].len=lxt2_rd_get_fac_len(GLOBALS->lx2_lx2_c_1, i);
74 	}
75 
76 fprintf(stderr, LXT2_RDLOAD"Finished building %d facs.\n", GLOBALS->numfacs);
77 /* SPLASH */                            splash_sync(1, 5);
78 
79 GLOBALS->first_cycle_lx2_c_1 = (TimeType) lxt2_rd_get_start_time(GLOBALS->lx2_lx2_c_1) * GLOBALS->time_scale;
80 GLOBALS->last_cycle_lx2_c_1 = (TimeType) lxt2_rd_get_end_time(GLOBALS->lx2_lx2_c_1) * GLOBALS->time_scale;
81 GLOBALS->total_cycles_lx2_c_1 = GLOBALS->last_cycle_lx2_c_1 - GLOBALS->first_cycle_lx2_c_1 + 1;
82 
83 /* do your stuff here..all useful info has been initialized by now */
84 
85 if(!GLOBALS->hier_was_explicitly_set)    /* set default hierarchy split char */
86         {
87         GLOBALS->hier_delimeter='.';
88         }
89 
90 if(GLOBALS->numfacs)
91 	{
92 	char *fnam = lxt2_rd_get_facname(GLOBALS->lx2_lx2_c_1, 0);
93 	int flen = strlen(fnam);
94 	f_name[0]=malloc_2(flen+1);
95 	strcpy(f_name[0], fnam);
96 	}
97 
98 for(i=0;i<GLOBALS->numfacs;i++)
99         {
100 	char buf[65537];
101 	char *str;
102 	struct fac *f;
103 
104 	if(i!=(GLOBALS->numfacs-1))
105 		{
106 		char *fnam = lxt2_rd_get_facname(GLOBALS->lx2_lx2_c_1, i+1);
107 		int flen = strlen(fnam);
108 		f_name[(i+1)&F_NAME_MODULUS]=malloc_2(flen+1);
109 		strcpy(f_name[(i+1)&F_NAME_MODULUS], fnam);
110 		}
111 
112 	if(i>1)
113 		{
114 		free_2(f_name[(i-2)&F_NAME_MODULUS]);
115 		f_name[(i-2)&F_NAME_MODULUS] = NULL;
116 		}
117 
118 	if(GLOBALS->mvlfacs_lx2_c_1[i].flags&LXT2_RD_SYM_F_ALIAS)
119 		{
120 		int alias = GLOBALS->mvlfacs_lx2_c_1[i].node_alias;
121 		f=GLOBALS->mvlfacs_lx2_c_1+alias;
122 
123 		while(f->flags&LXT2_RD_SYM_F_ALIAS)
124 			{
125 			f=GLOBALS->mvlfacs_lx2_c_1+f->node_alias;
126 			}
127 
128 		numalias++;
129 		}
130 		else
131 		{
132 		f=GLOBALS->mvlfacs_lx2_c_1+i;
133 		}
134 
135 	if((f->len>1)&& (!(f->flags&(LXT2_RD_SYM_F_INTEGER|LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING))) )
136 		{
137 		int len = sprintf(buf, "%s[%d:%d]", f_name[(i)&F_NAME_MODULUS],node_block[i].msi, node_block[i].lsi);
138 		str=malloc_2(len+1);
139 		if(!GLOBALS->alt_hier_delimeter)
140 			{
141 			strcpy(str, buf);
142 			}
143 			else
144 			{
145 			strcpy_vcdalt(str, buf, GLOBALS->alt_hier_delimeter);
146 			}
147                 s=&sym_block[i];
148                 symadd_name_exists_sym_exists(s,str,0);
149 		prevsymroot = prevsym = NULL;
150 		}
151 		else
152 		{
153                 int gatecmp = (f->len==1) && (!(f->flags&(LXT2_RD_SYM_F_INTEGER|LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING))) && (node_block[i].msi!=-1) && (node_block[i].lsi!=-1);
154                 int revcmp = gatecmp && (i) && (!strcmp(f_name[(i)&F_NAME_MODULUS], f_name[(i-1)&F_NAME_MODULUS]));
155 
156 		if(gatecmp)
157 			{
158 			int len = sprintf(buf, "%s[%d]", f_name[(i)&F_NAME_MODULUS],node_block[i].msi);
159 			str=malloc_2(len+1);
160 			if(!GLOBALS->alt_hier_delimeter)
161 				{
162 				strcpy(str, buf);
163 				}
164 				else
165 				{
166 				strcpy_vcdalt(str, buf, GLOBALS->alt_hier_delimeter);
167 				}
168 	                s=&sym_block[i];
169 	                symadd_name_exists_sym_exists(s,str,0);
170 			if((prevsym)&&(revcmp)&&(!strchr(f_name[(i)&F_NAME_MODULUS], '\\')))	/* allow chaining for search functions.. */
171 				{
172 				prevsym->vec_root = prevsymroot;
173 				prevsym->vec_chain = s;
174 				s->vec_root = prevsymroot;
175 				prevsym = s;
176 				}
177 				else
178 				{
179 				prevsymroot = prevsym = s;
180 				}
181 			}
182 			else
183 			{
184 			str=malloc_2(strlen(f_name[(i)&F_NAME_MODULUS])+1);
185 			if(!GLOBALS->alt_hier_delimeter)
186 				{
187 				strcpy(str, f_name[(i)&F_NAME_MODULUS]);
188 				}
189 				else
190 				{
191 				strcpy_vcdalt(str, f_name[(i)&F_NAME_MODULUS], GLOBALS->alt_hier_delimeter);
192 				}
193 	                s=&sym_block[i];
194 	                symadd_name_exists_sym_exists(s,str,0);
195 			prevsymroot = prevsym = NULL;
196 
197 			if(f->flags&LXT2_RD_SYM_F_INTEGER)
198 				{
199 				node_block[i].msi=31;
200 				node_block[i].lsi=0;
201 				GLOBALS->mvlfacs_lx2_c_1[i].len=32;
202 				}
203 			}
204 		}
205 
206 	n=&node_block[i];
207         n->nname=s->name;
208         n->mv.mvlfac = GLOBALS->mvlfacs_lx2_c_1+i;
209 	GLOBALS->mvlfacs_lx2_c_1[i].working_node = n;
210 
211 	if((f->len>1)||(f->flags&(LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING)))
212 		{
213 		n->extvals = 1;
214 		}
215 
216         n->head.time=-1;        /* mark 1st node as negative time */
217         n->head.v.h_val=AN_X;
218         s->n=n;
219         }
220 
221 for(i=0;i<=F_NAME_MODULUS;i++)
222 	{
223 	if(f_name[(i)&F_NAME_MODULUS])
224 		{
225 		free_2(f_name[(i)&F_NAME_MODULUS]);
226 		f_name[(i)&F_NAME_MODULUS] = NULL;
227 		}
228 	}
229 free_2(f_name); f_name = NULL;
230 
231 /* SPLASH */                            splash_sync(2, 5);
232 GLOBALS->facs=(struct symbol **)malloc_2(GLOBALS->numfacs*sizeof(struct symbol *));
233 
234 if(GLOBALS->fast_tree_sort)
235         {
236         for(i=0;i<GLOBALS->numfacs;i++)
237                 {
238                 int len;
239                 GLOBALS->facs[i]=&sym_block[i];
240                 if((len=strlen(GLOBALS->facs[i]->name))>GLOBALS->longestname) GLOBALS->longestname=len;
241                 }
242 
243 	if(numalias)
244 		{
245 		int idx_lft = 0;
246 		int idx_lftmax = GLOBALS->numfacs - numalias;
247 		int idx_rgh = GLOBALS->numfacs - numalias;
248 		struct symbol **facs_merge=(struct symbol **)malloc_2(GLOBALS->numfacs*sizeof(struct symbol *));
249 
250 		fprintf(stderr, LXT2_RDLOAD"Merging in %d aliases.\n", numalias);
251 
252 		for(i=0;i<GLOBALS->numfacs;i++)	/* fix possible tail appended aliases by remerging in partial one pass merge sort */
253 			{
254 			if(strcmp(GLOBALS->facs[idx_lft]->name, GLOBALS->facs[idx_rgh]->name) <= 0)
255 				{
256 				facs_merge[i] = GLOBALS->facs[idx_lft++];
257 
258 				if(idx_lft == idx_lftmax)
259 					{
260 					for(i++;i<GLOBALS->numfacs;i++)
261 						{
262 						facs_merge[i] = GLOBALS->facs[idx_rgh++];
263 						}
264 					}
265 				}
266 				else
267 				{
268 				facs_merge[i] = GLOBALS->facs[idx_rgh++];
269 
270 				if(idx_rgh == GLOBALS->numfacs)
271 					{
272 					for(i++;i<GLOBALS->numfacs;i++)
273 						{
274 						facs_merge[i] = GLOBALS->facs[idx_lft++];
275 						}
276 					}
277 				}
278 			}
279 
280 		free_2(GLOBALS->facs); GLOBALS->facs = facs_merge;
281 		}
282 
283 /* SPLASH */                            splash_sync(3, 5);
284         fprintf(stderr, LXT2_RDLOAD"Building facility hierarchy tree.\n");
285 
286         init_tree();
287         for(i=0;i<GLOBALS->numfacs;i++)
288                 {
289                 int esc = 0;
290                 char *subst = GLOBALS->facs[i]->name;
291                 char ch;
292 
293                 while((ch=(*subst)))
294                         {
295                         if(ch==GLOBALS->hier_delimeter) { if(esc) *subst = VCDNAM_ESCAPE; }
296                         else if(ch=='\\') { esc = 1; GLOBALS->escaped_names_found_vcd_c_1 = 1; }
297                         subst++;
298                         }
299 
300                 build_tree_from_name(GLOBALS->facs[i]->name, i);
301                 }
302 /* SPLASH */                            splash_sync(4, 5);
303 	if(GLOBALS->escaped_names_found_vcd_c_1)
304 	        {
305 		for(i=0;i<GLOBALS->numfacs;i++)
306 			{
307 		        char *subst, ch;
308 		        subst=GLOBALS->facs[i]->name;
309 		        while((ch=(*subst)))
310 		                {
311 		                if(ch==VCDNAM_ESCAPE) { *subst=GLOBALS->hier_delimeter; } /* restore back to normal */
312 		                subst++;
313 		                }
314 			}
315 	        }
316         treegraft(&GLOBALS->treeroot);
317 
318         fprintf(stderr, LXT2_RDLOAD"Sorting facility hierarchy tree.\n");
319         treesort(GLOBALS->treeroot, NULL);
320 
321 /* SPLASH */                            splash_sync(5, 5);
322         order_facs_from_treesort(GLOBALS->treeroot, &GLOBALS->facs);
323 	if(GLOBALS->escaped_names_found_vcd_c_1)
324 	        {
325 	        treenamefix(GLOBALS->treeroot);
326 	        }
327 
328         GLOBALS->facs_are_sorted=1;
329         }
330         else
331 	{
332 	for(i=0;i<GLOBALS->numfacs;i++)
333 		{
334 		char *subst, ch;
335 		int len;
336 		int esc = 0;
337 
338 		GLOBALS->facs[i]=&sym_block[i];
339 	        if((len=strlen(subst=GLOBALS->facs[i]->name))>GLOBALS->longestname) GLOBALS->longestname=len;
340 		while((ch=(*subst)))
341 			{
342 #ifdef WAVE_HIERFIX
343 	                if(ch==GLOBALS->hier_delimeter) { *subst=(!esc) ? VCDNAM_HIERSORT : VCDNAM_ESCAPE; }    /* forces sort at hier boundaries */
344 #else
345 	                if((ch==GLOBALS->hier_delimeter)&&(esc)) { *subst = VCDNAM_ESCAPE; }    /* forces sort at hier boundaries */
346 #endif
347 	                else if(ch=='\\') { esc = 1; GLOBALS->escaped_names_found_vcd_c_1 = 1; }
348 	                subst++;
349 			}
350 		}
351 
352 /* SPLASH */                            splash_sync(3, 5);
353 	fprintf(stderr, LXT2_RDLOAD"Sorting facilities at hierarchy boundaries.\n");
354 	wave_heapsort(GLOBALS->facs,GLOBALS->numfacs);
355 
356 #ifdef WAVE_HIERFIX
357 	for(i=0;i<GLOBALS->numfacs;i++)
358 		{
359 		char *subst, ch;
360 
361 		subst=GLOBALS->facs[i]->name;
362 		while((ch=(*subst)))
363 			{
364 			if(ch==VCDNAM_HIERSORT) { *subst=GLOBALS->hier_delimeter; }	/* restore back to normal */
365 			subst++;
366 			}
367 		}
368 #endif
369 
370 	GLOBALS->facs_are_sorted=1;
371 
372 /* SPLASH */                            splash_sync(4, 5);
373 	fprintf(stderr, LXT2_RDLOAD"Building facility hierarchy tree.\n");
374 
375 	init_tree();
376 	for(i=0;i<GLOBALS->numfacs;i++)
377 		{
378 		char *nf = GLOBALS->facs[i]->name;
379 	        build_tree_from_name(nf, i);
380 		}
381 /* SPLASH */                            splash_sync(5, 5);
382 	if(GLOBALS->escaped_names_found_vcd_c_1)
383 	        {
384 		for(i=0;i<GLOBALS->numfacs;i++)
385 			{
386 		        char *subst, ch;
387 		        subst=GLOBALS->facs[i]->name;
388 		        while((ch=(*subst)))
389 		                {
390 		                if(ch==VCDNAM_ESCAPE) { *subst=GLOBALS->hier_delimeter; } /* restore back to normal */
391 		                subst++;
392 		                }
393 			}
394 	        }
395 	treegraft(&GLOBALS->treeroot);
396 	treesort(GLOBALS->treeroot, NULL);
397 	if(GLOBALS->escaped_names_found_vcd_c_1)
398 	        {
399 	        treenamefix(GLOBALS->treeroot);
400 	        }
401 	}
402 
403 GLOBALS->min_time = GLOBALS->first_cycle_lx2_c_1; GLOBALS->max_time=GLOBALS->last_cycle_lx2_c_1;
404 GLOBALS->is_lx2 = LXT2_IS_LXT2;
405 
406 if(skip_start || skip_end)
407 	{
408 	TimeType b_start, b_end;
409 
410 	if(!skip_start) b_start = GLOBALS->min_time; else b_start = unformat_time(skip_start, GLOBALS->time_dimension);
411 	if(!skip_end) b_end = GLOBALS->max_time; else b_end = unformat_time(skip_end, GLOBALS->time_dimension);
412 
413 	if(b_start<GLOBALS->min_time) b_start = GLOBALS->min_time;
414 	else if(b_start>GLOBALS->max_time) b_start = GLOBALS->max_time;
415 
416 	if(b_end<GLOBALS->min_time) b_end = GLOBALS->min_time;
417 	else if(b_end>GLOBALS->max_time) b_end = GLOBALS->max_time;
418 
419         if(b_start > b_end)
420                 {
421 		TimeType tmp_time = b_start;
422                 b_start = b_end;
423                 b_end = tmp_time;
424                 }
425 
426 	if(!lxt2_rd_limit_time_range(GLOBALS->lx2_lx2_c_1, b_start, b_end))
427 		{
428 		fprintf(stderr, LXT2_RDLOAD"--begin/--end options yield zero blocks, ignoring.\n");
429 		lxt2_rd_unlimit_time_range(GLOBALS->lx2_lx2_c_1);
430 		}
431 		else
432 		{
433 		GLOBALS->min_time = b_start;
434 		GLOBALS->max_time = b_end;
435 		}
436 	}
437 
438 /* SPLASH */                            splash_finalize();
439 return(GLOBALS->max_time);
440 }
441 
442 
443 /*
444  * lx2 callback (only does bits for now)
445  */
lx2_callback(struct lxt2_rd_trace ** lt,lxtint64_t * tim,lxtint32_t * facidx,char ** value)446 static void lx2_callback(struct lxt2_rd_trace **lt, lxtint64_t *tim, lxtint32_t *facidx, char **value)
447 {
448 (void)lt;
449 
450 struct HistEnt *htemp = histent_calloc();
451 struct lx2_entry *l2e = GLOBALS->lx2_table_lx2_c_1+(*facidx);
452 struct fac *f = GLOBALS->mvlfacs_lx2_c_1+(*facidx);
453 
454 
455 GLOBALS->busycnt_lx2_c_1++;
456 if(GLOBALS->busycnt_lx2_c_1==WAVE_BUSY_ITER)
457         {
458         busy_window_refresh();
459         GLOBALS->busycnt_lx2_c_1 = 0;
460         }
461 
462 /* fprintf(stderr, "%lld %d %s\n", *tim, *facidx, *value); */
463 
464 if(!(f->flags&(LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING)))
465 	{
466 	if(f->len>1)
467 	        {
468 	        htemp->v.h_vector = (char *)malloc_2(f->len);
469 		memcpy(htemp->v.h_vector, *value, f->len);
470 	        }
471 	        else
472 	        {
473 		switch(**value)
474 			{
475 			case '0':	htemp->v.h_val = AN_0; break;
476 			case '1':	htemp->v.h_val = AN_1; break;
477 			case 'Z':
478 			case 'z':	htemp->v.h_val = AN_Z; break;
479 			default:	htemp->v.h_val = AN_X; break;
480 			}
481 	        }
482 	}
483 else if(f->flags&LXT2_RD_SYM_F_DOUBLE)
484 	{
485 #ifdef WAVE_HAS_H_DOUBLE
486 	sscanf(*value, "%lg", &htemp->v.h_double);
487 #else
488 	double *d = malloc_2(sizeof(double));
489 	sscanf(*value, "%lg", d);
490 	htemp->v.h_vector = (char *)d;
491 #endif
492 	htemp->flags = HIST_REAL;
493 	}
494 else	/* string */
495 	{
496 	char *s = malloc_2(strlen(*value)+1);
497 	strcpy(s, *value);
498 	htemp->v.h_vector = s;
499 	htemp->flags = HIST_REAL|HIST_STRING;
500 	}
501 
502 
503 htemp->time = (*tim) * (GLOBALS->time_scale);
504 
505 if(l2e->histent_head)
506 	{
507 	l2e->histent_curr->next = htemp;
508 	l2e->histent_curr = htemp;
509 	}
510 	else
511 	{
512 	l2e->histent_head = l2e->histent_curr = htemp;
513 	}
514 
515 l2e->numtrans++;
516 }
517 
518 
519 /*
520  * this is the black magic that handles aliased signals...
521  */
lx2_resolver(nptr np,nptr resolve)522 static void lx2_resolver(nptr np, nptr resolve)
523 {
524 np->extvals = resolve->extvals;
525 np->msi = resolve->msi;
526 np->lsi = resolve->lsi;
527 memcpy(&np->head, &resolve->head, sizeof(struct HistEnt));
528 np->curr = resolve->curr;
529 np->harray = resolve->harray;
530 np->numhist = resolve->numhist;
531 np->mv.mvlfac=NULL;
532 }
533 
534 
535 
536 /*
537  * actually import an lx2 trace but don't do it if it's already been imported
538  */
import_lx2_trace(nptr np)539 void import_lx2_trace(nptr np)
540 {
541 struct HistEnt *htemp, *histent_tail;
542 int len, i;
543 struct fac *f;
544 int txidx;
545 nptr nold = np;
546 
547 switch(GLOBALS->is_lx2)
548 	{
549 #ifdef AET2_IS_PRESENT
550 	case LXT2_IS_AET2: 	import_ae2_trace(np); return;
551 #endif
552 	case LXT2_IS_VZT:  	import_vzt_trace(np); return;
553 	case LXT2_IS_VLIST: 	import_vcd_trace(np); return;
554 	case LXT2_IS_FST: 	import_fst_trace(np); return;
555 	case LXT2_IS_FSDB:	import_extload_trace(np); return;
556 	default: break; /* fallthrough */
557 	}
558 
559 if(!(f=np->mv.mvlfac)) return;	/* already imported */
560 
561 txidx = f - GLOBALS->mvlfacs_lx2_c_1;
562 if(np->mv.mvlfac->flags&LXT2_RD_SYM_F_ALIAS)
563 	{
564 	txidx = lxt2_rd_get_alias_root(GLOBALS->lx2_lx2_c_1, txidx);
565 	np = GLOBALS->mvlfacs_lx2_c_1[txidx].working_node;
566 
567 	if(!(f=np->mv.mvlfac))
568 		{
569 		lx2_resolver(nold, np);
570 		return;	/* already imported */
571 		}
572 	}
573 
574 fprintf(stderr, "Import: %s\n", np->nname);
575 
576 /* new stuff */
577 len = np->mv.mvlfac->len;
578 
579 if(f->node_alias <= 1) /* sorry, arrays not supported, but lx2 doesn't support them yet either */
580 	{
581 	lxt2_rd_set_fac_process_mask(GLOBALS->lx2_lx2_c_1, txidx);
582 	lxt2_rd_iter_blocks(GLOBALS->lx2_lx2_c_1, lx2_callback, NULL);
583 	lxt2_rd_clr_fac_process_mask(GLOBALS->lx2_lx2_c_1, txidx);
584 	}
585 
586 histent_tail = htemp = histent_calloc();
587 if(len>1)
588 	{
589 	htemp->v.h_vector = (char *)malloc_2(len);
590 	for(i=0;i<len;i++) htemp->v.h_vector[i] = AN_Z;
591 	}
592 	else
593 	{
594 	htemp->v.h_val = AN_Z;		/* z */
595 	}
596 htemp->time = MAX_HISTENT_TIME;
597 
598 htemp = histent_calloc();
599 if(len>1)
600 	{
601 	htemp->v.h_vector = (char *)malloc_2(len);
602 	for(i=0;i<len;i++) htemp->v.h_vector[i] = AN_X;
603 	}
604 	else
605 	{
606 	htemp->v.h_val = AN_X;		/* x */
607 	}
608 htemp->time = MAX_HISTENT_TIME-1;
609 htemp->next = histent_tail;
610 
611 if(GLOBALS->lx2_table_lx2_c_1[txidx].histent_curr)
612 	{
613 	GLOBALS->lx2_table_lx2_c_1[txidx].histent_curr->next = htemp;
614 	htemp = GLOBALS->lx2_table_lx2_c_1[txidx].histent_head;
615 	}
616 
617 if(!(f->flags&(LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING)))
618         {
619 	if(len>1)
620 		{
621 		np->head.v.h_vector = (char *)malloc_2(len);
622 		for(i=0;i<len;i++) np->head.v.h_vector[i] = AN_X;
623 		}
624 		else
625 		{
626 		np->head.v.h_val = AN_X;	/* x */
627 		}
628 	}
629         else
630         {
631         np->head.flags = HIST_REAL;
632         if(f->flags&LXT2_RD_SYM_F_STRING) np->head.flags |= HIST_STRING;
633         }
634 
635         {
636         struct HistEnt *htemp2 = histent_calloc();
637         htemp2->time = -1;
638         if(len>1)
639                 {
640                 htemp2->v.h_vector = htemp->v.h_vector;
641                 }
642                 else
643                 {
644                 htemp2->v.h_val = htemp->v.h_val;
645                 }
646         htemp2->next = htemp;
647         htemp = htemp2;
648 	GLOBALS->lx2_table_lx2_c_1[txidx].numtrans++;
649         }
650 
651 np->head.time  = -2;
652 np->head.next = htemp;
653 np->numhist=GLOBALS->lx2_table_lx2_c_1[txidx].numtrans +2 /*endcap*/ +1 /*frontcap*/;
654 
655 memset(GLOBALS->lx2_table_lx2_c_1+txidx, 0, sizeof(struct lx2_entry));	/* zero it out */
656 
657 np->curr = histent_tail;
658 np->mv.mvlfac = NULL;	/* it's imported and cached so we can forget it's an mvlfac now */
659 
660 if(nold!=np)
661 	{
662 	lx2_resolver(nold, np);
663 	}
664 }
665 
666 
667 /*
668  * pre-import many traces at once so function above doesn't have to iterate...
669  */
lx2_set_fac_process_mask(nptr np)670 void lx2_set_fac_process_mask(nptr np)
671 {
672 struct fac *f;
673 int txidx;
674 
675 switch(GLOBALS->is_lx2)
676         {
677 #ifdef AET2_IS_PRESENT
678         case LXT2_IS_AET2: 	ae2_set_fac_process_mask(np); return;
679 #endif
680         case LXT2_IS_VZT:  	vzt_set_fac_process_mask(np); return;
681 	case LXT2_IS_VLIST: 	vcd_set_fac_process_mask(np); return;
682 	case LXT2_IS_FST: 	fst_set_fac_process_mask(np); return;
683 	case LXT2_IS_FSDB:	fsdb_set_fac_process_mask(np); return;
684         default: break; /* fallthrough */
685         }
686 
687 if(!(f=np->mv.mvlfac)) return;	/* already imported */
688 
689 txidx = f-GLOBALS->mvlfacs_lx2_c_1;
690 
691 if(np->mv.mvlfac->flags&LXT2_RD_SYM_F_ALIAS)
692 	{
693 	txidx = lxt2_rd_get_alias_root(GLOBALS->lx2_lx2_c_1, txidx);
694 	np = GLOBALS->mvlfacs_lx2_c_1[txidx].working_node;
695 
696 	if(!(np->mv.mvlfac)) return;	/* already imported */
697 	}
698 
699 if(np->mv.mvlfac->node_alias <= 1) /* sorry, arrays not supported, but lx2 doesn't support them yet either */
700 	{
701 	lxt2_rd_set_fac_process_mask(GLOBALS->lx2_lx2_c_1, txidx);
702 	GLOBALS->lx2_table_lx2_c_1[txidx].np = np;
703 	}
704 }
705 
706 
lx2_import_masked(void)707 void lx2_import_masked(void)
708 {
709 int txidx, i, cnt;
710 
711 switch(GLOBALS->is_lx2)
712         {
713 #ifdef AET2_IS_PRESENT
714         case LXT2_IS_AET2: 	ae2_import_masked(); return;
715 #endif
716         case LXT2_IS_VZT:  	vzt_import_masked(); return;
717         case LXT2_IS_VLIST:  	vcd_import_masked(); return;
718         case LXT2_IS_FST:  	fst_import_masked(); return;
719 	case LXT2_IS_FSDB:	fsdb_import_masked(); return;
720         default: break; /* fallthrough */
721         }
722 
723 cnt = 0;
724 for(txidx=0;txidx<GLOBALS->numfacs;txidx++)
725 	{
726 	if(lxt2_rd_get_fac_process_mask(GLOBALS->lx2_lx2_c_1, txidx))
727 		{
728 		cnt++;
729 		}
730 	}
731 
732 if(!cnt) return;
733 
734 if(cnt>100)
735 	{
736 	fprintf(stderr, LXT2_RDLOAD"Extracting %d traces\n", cnt);
737 	}
738 
739 
740 set_window_busy(NULL);
741 lxt2_rd_iter_blocks(GLOBALS->lx2_lx2_c_1, lx2_callback, NULL);
742 set_window_idle(NULL);
743 
744 for(txidx=0;txidx<GLOBALS->numfacs;txidx++)
745 	{
746 	if(lxt2_rd_get_fac_process_mask(GLOBALS->lx2_lx2_c_1, txidx))
747 		{
748 		struct HistEnt *htemp, *histent_tail;
749 		struct fac *f = GLOBALS->mvlfacs_lx2_c_1+txidx;
750 		int len = f->len;
751 		nptr np = GLOBALS->lx2_table_lx2_c_1[txidx].np;
752 
753 		histent_tail = htemp = histent_calloc();
754 		if(f->flags&(LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING))
755 			{
756 			htemp->v.h_vector = strdup_2((f->flags&LXT2_RD_SYM_F_DOUBLE) ? "NaN" : "UNDEF");
757 			htemp->flags = HIST_REAL;
758 		        if(f->flags&LXT2_RD_SYM_F_STRING) htemp->flags |= HIST_STRING;
759 			}
760 			else
761 			{
762 			if(len>1)
763 				{
764 				htemp->v.h_vector = (char *)malloc_2(len);
765 				for(i=0;i<len;i++) htemp->v.h_vector[i] = AN_Z;
766 				}
767 				else
768 				{
769 				htemp->v.h_val = AN_Z;		/* z */
770 				}
771 			}
772 		htemp->time = MAX_HISTENT_TIME;
773 
774 		htemp = histent_calloc();
775 		if(f->flags&(LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING))
776 			{
777 			htemp->v.h_vector = strdup_2((f->flags&LXT2_RD_SYM_F_DOUBLE) ? "NaN" : "UNDEF");
778 			htemp->flags = HIST_REAL;
779 		        if(f->flags&LXT2_RD_SYM_F_STRING) htemp->flags |= HIST_STRING;
780 			}
781 			else
782 			{
783 			if(len>1)
784 				{
785 				htemp->v.h_vector = (char *)malloc_2(len);
786 				for(i=0;i<len;i++) htemp->v.h_vector[i] = AN_X;
787 				}
788 				else
789 				{
790 				htemp->v.h_val = AN_X;		/* x */
791 				}
792 			}
793 		htemp->time = MAX_HISTENT_TIME-1;
794 		htemp->next = histent_tail;
795 
796 		if(GLOBALS->lx2_table_lx2_c_1[txidx].histent_curr)
797 			{
798 			GLOBALS->lx2_table_lx2_c_1[txidx].histent_curr->next = htemp;
799 			htemp = GLOBALS->lx2_table_lx2_c_1[txidx].histent_head;
800 			}
801 
802 		if(!(f->flags&(LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING)))
803 		        {
804 			if(len>1)
805 				{
806 				np->head.v.h_vector = (char *)malloc_2(len);
807 				for(i=0;i<len;i++) np->head.v.h_vector[i] = AN_X;
808 				}
809 				else
810 				{
811 				np->head.v.h_val = AN_X;	/* x */
812 				}
813 			}
814 		        else
815 		        {
816 		        np->head.flags = HIST_REAL;
817 		        if(f->flags&LXT2_RD_SYM_F_STRING) np->head.flags |= HIST_STRING;
818 
819 			np->head.v.h_vector = strdup_2((f->flags&LXT2_RD_SYM_F_DOUBLE) ? "NaN" : "UNDEF");
820 		        }
821 
822 	        {
823 	        struct HistEnt *htemp2 = histent_calloc();
824 	        htemp2->time = -1;
825 
826 		if(f->flags&(LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING))
827 			{
828 			htemp2->v.h_vector = strdup_2((f->flags&LXT2_RD_SYM_F_DOUBLE) ? "NaN" : "UNDEF");
829 			htemp2->flags = HIST_REAL;
830 		        if(f->flags&LXT2_RD_SYM_F_STRING) htemp2->flags |= HIST_STRING;
831 			}
832 			else
833 			{
834 		        if(len>1)
835 		                {
836 		                htemp2->v.h_vector = htemp->v.h_vector;
837 		                }
838 		                else
839 		                {
840 		                htemp2->v.h_val = htemp->v.h_val;
841 		                }
842 			}
843 	        htemp2->next = htemp;
844 	        htemp = htemp2;
845 	        GLOBALS->lx2_table_lx2_c_1[txidx].numtrans++;
846 	        }
847 
848 		np->head.time  = -2;
849 		np->head.next = htemp;
850 		np->numhist=GLOBALS->lx2_table_lx2_c_1[txidx].numtrans +2 /*endcap*/ +1 /*frontcap*/;
851 
852 		memset(GLOBALS->lx2_table_lx2_c_1+txidx, 0, sizeof(struct lx2_entry));	/* zero it out */
853 
854 		np->curr = histent_tail;
855 		np->mv.mvlfac = NULL;	/* it's imported and cached so we can forget it's an mvlfac now */
856 		lxt2_rd_clr_fac_process_mask(GLOBALS->lx2_lx2_c_1, txidx);
857 		}
858 	}
859 }
860 
861