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