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