1 /*
2  * Copyright (c) 2001-2012 Tony Bybell.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include <config.h>
24 #include "lxt_write.h"
25 
26 /*
27  * in-place sort to keep chained facs from migrating...
28  */
wave_mergesort(struct lt_symbol ** a,struct lt_symbol ** b,int lo,int hi)29 static void wave_mergesort(struct lt_symbol **a, struct lt_symbol **b, int lo, int hi)
30 {
31 int i, j, k;
32 
33 if (lo<hi)
34 	{
35         int mid=(lo+hi)/2;
36 
37         wave_mergesort(a, b, lo, mid);
38         wave_mergesort(a, b, mid+1, hi);
39 
40     	i=0; j=lo;
41     	while (j<=mid)
42 		{
43         	b[i++]=a[j++];
44 		}
45 
46     	i=0; k=lo;
47     	while ((k<j)&&(j<=hi))
48 		{
49         	if (strcmp(b[i]->name, a[j]->name) <= 0)
50 			{
51             		a[k++]=b[i++];
52 			}
53 			else
54 			{
55 	            	a[k++]=a[j++];
56 			}
57 		}
58 
59     	while (k<j)
60 		{
61         	a[k++]=b[i++];
62 		}
63 	}
64 }
65 
wave_msort(struct lt_symbol ** a,int num)66 static void wave_msort(struct lt_symbol **a, int num)
67 {
68 struct lt_symbol **b = malloc(((num/2)+1) * sizeof(struct lt_symbol *));
69 
70 wave_mergesort(a, b, 0, num-1);
71 
72 free(b);
73 }
74 
75 /************************ splay ************************/
76 
77 static int dslxt_success;
78 
dslxt_splay(char * i,dslxt_Tree * t)79 static dslxt_Tree * dslxt_splay (char *i, dslxt_Tree * t) {
80 /* Simple top down splay, not requiring i to be in the tree t.  */
81 /* What it does is described above.                             */
82     dslxt_Tree N, *l, *r, *y;
83     int dir;
84 
85     dslxt_success = 0;
86 
87     if (t == NULL) return t;
88     N.left = N.right = NULL;
89     l = r = &N;
90 
91     for (;;) {
92 	dir = strcmp(i, t->item);
93 	if (dir < 0) {
94 	    if (t->left == NULL) break;
95 	    if (strcmp(i, t->left->item)<0) {
96 		y = t->left;                           /* rotate right */
97 		t->left = y->right;
98 		y->right = t;
99 		t = y;
100 		if (t->left == NULL) break;
101 	    }
102 	    r->left = t;                               /* link right */
103 	    r = t;
104 	    t = t->left;
105 	} else if (dir > 0) {
106 	    if (t->right == NULL) break;
107 	    if (strcmp(i, t->right->item)>0) {
108 		y = t->right;                          /* rotate left */
109 		t->right = y->left;
110 		y->left = t;
111 		t = y;
112 		if (t->right == NULL) break;
113 	    }
114 	    l->right = t;                              /* link left */
115 	    l = t;
116 	    t = t->right;
117 	} else {
118 	    dslxt_success=1;
119 	    break;
120 	}
121     }
122     l->right = t->left;                                /* assemble */
123     r->left = t->right;
124     t->left = N.right;
125     t->right = N.left;
126     return t;
127 }
128 
129 
dslxt_insert(char * i,dslxt_Tree * t,unsigned int val)130 static dslxt_Tree * dslxt_insert(char *i, dslxt_Tree * t, unsigned int val) {
131 /* Insert i into the tree t, unless it's already there.    */
132 /* Return a pointer to the resulting tree.                 */
133     dslxt_Tree * n;
134     int dir;
135 
136     n = (dslxt_Tree *) calloc (1, sizeof (dslxt_Tree));
137     if (n == NULL) {
138 	fprintf(stderr, "dslxt_insert: ran out of memory, exiting.\n");
139 	exit(255);
140     }
141     n->item = i;
142     n->val  = val;
143     if (t == NULL) {
144 	n->left = n->right = NULL;
145 	return n;
146     }
147     t = dslxt_splay(i,t);
148     dir = strcmp(i,t->item);
149     if (dir<0) {
150 	n->left = t->left;
151 	n->right = t;
152 	t->left = NULL;
153 	return n;
154     } else if (dir>0) {
155 	n->right = t->right;
156 	n->left = t;
157 	t->right = NULL;
158 	return n;
159     } else { /* We get here if it's already in the tree */
160              /* Don't add it again                      */
161 	free(n);
162 	return t;
163     }
164 }
165 
166 #if 0
167 /* unused for now but delete is here for completeness   */
168 static dslxt_Tree * dslxt_delete(char *i, dslxt_Tree * t) {
169 /* Deletes i from the tree if it's there.               */
170 /* Return a pointer to the resulting tree.              */
171     dslxt_Tree * x;
172     if (t==NULL) return NULL;
173     t = dslxt_splay(i,t);
174     if (!strcmp(i, t->item)) {               /* found it */
175 	if (t->left == NULL) {
176 	    x = t->right;
177 	} else {
178 	    x = dslxt_splay(i, t->left);
179 	    x->right = t->right;
180 	}
181 	free(t);
182 	return x;
183     }
184     return t;                         /* It wasn't there */
185 }
186 #endif
187 
188 /************************ splay ************************/
189 
190 /*
191  * functions which emit various big endian
192  * data to a file
193  */
lt_emit_u8(struct lt_trace * lt,int value)194 static int lt_emit_u8(struct lt_trace *lt, int value)
195 {
196 unsigned char buf[1];
197 int nmemb;
198 
199 buf[0] = value & 0xff;
200 nmemb=fwrite(buf, sizeof(char), 1, lt->handle);
201 lt->position+=nmemb;
202 return(nmemb);
203 }
204 
205 
lt_emit_u16(struct lt_trace * lt,int value)206 static int lt_emit_u16(struct lt_trace *lt, int value)
207 {
208 unsigned char buf[2];
209 int nmemb;
210 
211 buf[0] = (value>>8) & 0xff;
212 buf[1] = value & 0xff;
213 nmemb = fwrite(buf, sizeof(char), 2, lt->handle);
214 lt->position+=nmemb;
215 return(nmemb);
216 }
217 
218 
lt_emit_u24(struct lt_trace * lt,int value)219 static int lt_emit_u24(struct lt_trace *lt, int value)
220 {
221 unsigned char buf[3];
222 int nmemb;
223 
224 buf[0] = (value>>16) & 0xff;
225 buf[1] = (value>>8) & 0xff;
226 buf[2] = value & 0xff;
227 nmemb=fwrite(buf, sizeof(char), 3, lt->handle);
228 lt->position+=nmemb;
229 return(nmemb);
230 }
231 
232 
lt_emit_u32(struct lt_trace * lt,int value)233 static int lt_emit_u32(struct lt_trace *lt, int value)
234 {
235 unsigned char buf[4];
236 int nmemb;
237 
238 buf[0] = (value>>24) & 0xff;
239 buf[1] = (value>>16) & 0xff;
240 buf[2] = (value>>8) & 0xff;
241 buf[3] = value & 0xff;
242 nmemb=fwrite(buf, sizeof(char), 4, lt->handle);
243 lt->position+=nmemb;
244 return(nmemb);
245 }
246 
247 
lt_emit_u64(struct lt_trace * lt,int valueh,int valuel)248 static int lt_emit_u64(struct lt_trace *lt, int valueh, int valuel)
249 {
250 int rc;
251 
252 if((rc=lt_emit_u32(lt, valueh)))
253 	{
254 	rc=lt_emit_u32(lt, valuel);
255 	}
256 
257 return(rc);
258 }
259 
260 
lt_emit_double(struct lt_trace * lt,double value)261 static int lt_emit_double(struct lt_trace *lt, double value)
262 {
263 int nmemb;
264 
265 nmemb=fwrite(&value, sizeof(char), sizeof(double)/sizeof(char), lt->handle);
266 lt->position+=nmemb;
267 return(nmemb);
268 }
269 
270 
lt_emit_string(struct lt_trace * lt,char * value)271 static int lt_emit_string(struct lt_trace *lt, char *value)
272 {
273 int rc=1;
274 do
275 	{
276         rc&=lt_emit_u8(lt, *value);
277         } while(*(value++));
278 return(rc);
279 }
280 
281 
282 /*
283  * gzfunctions which emit various big endian
284  * data to a file.  (lt->position needs to be
285  * fixed up on gzclose so the tables don't
286  * get out of sync!)
287  */
lt_emit_u8z(struct lt_trace * lt,int value)288 static int lt_emit_u8z(struct lt_trace *lt, int value)
289 {
290 unsigned char buf[1];
291 int nmemb;
292 
293 buf[0] = value & 0xff;
294 nmemb=gzwrite(lt->zhandle, buf, 1);
295 lt->zpackcount++;
296 lt->position++;
297 return(nmemb);
298 }
299 
300 
lt_emit_u16z(struct lt_trace * lt,int value)301 static int lt_emit_u16z(struct lt_trace *lt, int value)
302 {
303 unsigned char buf[2];
304 int nmemb;
305 
306 buf[0] = (value>>8) & 0xff;
307 buf[1] = value & 0xff;
308 nmemb = gzwrite(lt->zhandle, buf, 2);
309 lt->zpackcount+=2;
310 lt->position+=2;
311 return(nmemb);
312 }
313 
314 
lt_emit_u24z(struct lt_trace * lt,int value)315 static int lt_emit_u24z(struct lt_trace *lt, int value)
316 {
317 unsigned char buf[3];
318 int nmemb;
319 
320 buf[0] = (value>>16) & 0xff;
321 buf[1] = (value>>8) & 0xff;
322 buf[2] = value & 0xff;
323 nmemb=gzwrite(lt->zhandle, buf, 3);
324 lt->zpackcount+=3;
325 lt->position+=3;
326 return(nmemb);
327 }
328 
329 
lt_emit_u32z(struct lt_trace * lt,int value)330 static int lt_emit_u32z(struct lt_trace *lt, int value)
331 {
332 unsigned char buf[4];
333 int nmemb;
334 
335 buf[0] = (value>>24) & 0xff;
336 buf[1] = (value>>16) & 0xff;
337 buf[2] = (value>>8) & 0xff;
338 buf[3] = value & 0xff;
339 nmemb=gzwrite(lt->zhandle, buf, 4);
340 
341 lt->zpackcount+=4;
342 lt->position+=4;
343 return(nmemb);
344 }
345 
346 
lt_emit_u64z(struct lt_trace * lt,int valueh,int valuel)347 static int lt_emit_u64z(struct lt_trace *lt, int valueh, int valuel)
348 {
349 int rc;
350 
351 if((rc=lt_emit_u32z(lt, valueh)))
352 	{
353 	rc=lt_emit_u32z(lt, valuel);
354 	}
355 
356 return(rc);
357 }
358 
359 
lt_emit_doublez(struct lt_trace * lt,double value)360 static int lt_emit_doublez(struct lt_trace *lt, double value)
361 {
362 int nmemb;
363 
364 nmemb=gzwrite(lt->zhandle, &value, sizeof(double)/sizeof(char));
365 lt->zpackcount+=(sizeof(double)/sizeof(char));
366 lt->position+=(sizeof(double)/sizeof(char));;
367 return(nmemb);
368 }
369 
370 
lt_emit_stringz(struct lt_trace * lt,char * value)371 static int lt_emit_stringz(struct lt_trace *lt, char *value)
372 {
373 int rc=1;
374 do
375 	{
376         rc&=lt_emit_u8z(lt, *value);
377         } while(*(value++));
378 return(rc);
379 }
380 
381 /*
382  * bz2functions which emit various big endian
383  * data to a file.  (lt->position needs to be
384  * fixed up on BZ2_bzclose so the tables don't
385  * get out of sync!)
386  */
lt_emit_u8bz(struct lt_trace * lt,int value)387 static int lt_emit_u8bz(struct lt_trace *lt, int value)
388 {
389 unsigned char buf[1];
390 int nmemb;
391 
392 buf[0] = value & 0xff;
393 nmemb=BZ2_bzwrite(lt->zhandle, buf, 1);
394 lt->zpackcount++;
395 lt->position++;
396 return(nmemb);
397 }
398 
399 
lt_emit_u16bz(struct lt_trace * lt,int value)400 static int lt_emit_u16bz(struct lt_trace *lt, int value)
401 {
402 unsigned char buf[2];
403 int nmemb;
404 
405 buf[0] = (value>>8) & 0xff;
406 buf[1] = value & 0xff;
407 nmemb = BZ2_bzwrite(lt->zhandle, buf, 2);
408 lt->zpackcount+=2;
409 lt->position+=2;
410 return(nmemb);
411 }
412 
413 
lt_emit_u24bz(struct lt_trace * lt,int value)414 static int lt_emit_u24bz(struct lt_trace *lt, int value)
415 {
416 unsigned char buf[3];
417 int nmemb;
418 
419 buf[0] = (value>>16) & 0xff;
420 buf[1] = (value>>8) & 0xff;
421 buf[2] = value & 0xff;
422 nmemb=BZ2_bzwrite(lt->zhandle, buf, 3);
423 lt->zpackcount+=3;
424 lt->position+=3;
425 return(nmemb);
426 }
427 
428 
lt_emit_u32bz(struct lt_trace * lt,int value)429 static int lt_emit_u32bz(struct lt_trace *lt, int value)
430 {
431 unsigned char buf[4];
432 int nmemb;
433 
434 buf[0] = (value>>24) & 0xff;
435 buf[1] = (value>>16) & 0xff;
436 buf[2] = (value>>8) & 0xff;
437 buf[3] = value & 0xff;
438 nmemb=BZ2_bzwrite(lt->zhandle, buf, 4);
439 
440 lt->zpackcount+=4;
441 lt->position+=4;
442 return(nmemb);
443 }
444 
445 
lt_emit_u64bz(struct lt_trace * lt,int valueh,int valuel)446 static int lt_emit_u64bz(struct lt_trace *lt, int valueh, int valuel)
447 {
448 int rc;
449 
450 if((rc=lt_emit_u32bz(lt, valueh)))
451 	{
452 	rc=lt_emit_u32bz(lt, valuel);
453 	}
454 
455 return(rc);
456 }
457 
458 
lt_emit_doublebz(struct lt_trace * lt,double value)459 static int lt_emit_doublebz(struct lt_trace *lt, double value)
460 {
461 int nmemb;
462 
463 nmemb=BZ2_bzwrite(lt->zhandle, &value, sizeof(double)/sizeof(char));
464 lt->zpackcount+=(sizeof(double)/sizeof(char));
465 lt->position+=(sizeof(double)/sizeof(char));;
466 return(nmemb);
467 }
468 
469 
lt_emit_stringbz(struct lt_trace * lt,char * value)470 static int lt_emit_stringbz(struct lt_trace *lt, char *value)
471 {
472 int rc=1;
473 do
474 	{
475         rc&=lt_emit_u8bz(lt, *value);
476         } while(*(value++));
477 return(rc);
478 }
479 
480 
481 /*
482  * switch between compression modes above
483  */
lt_set_zmode(struct lt_trace * lt,int mode)484 static void lt_set_zmode(struct lt_trace *lt, int mode)
485 {
486 switch(mode)
487 	{
488 	case LT_ZMODE_NONE:
489 	lt->lt_emit_u8 = lt_emit_u8;
490 	lt->lt_emit_u16 = lt_emit_u16;
491 	lt->lt_emit_u24 = lt_emit_u24;
492 	lt->lt_emit_u32 = lt_emit_u32;
493 	lt->lt_emit_u64 = lt_emit_u64;
494 	lt->lt_emit_double = lt_emit_double;
495 	lt->lt_emit_string = lt_emit_string;
496 	break;
497 
498 	case LT_ZMODE_GZIP:
499 	lt->lt_emit_u8 = lt_emit_u8z;
500 	lt->lt_emit_u16 = lt_emit_u16z;
501 	lt->lt_emit_u24 = lt_emit_u24z;
502 	lt->lt_emit_u32 = lt_emit_u32z;
503 	lt->lt_emit_u64 = lt_emit_u64z;
504 	lt->lt_emit_double = lt_emit_doublez;
505 	lt->lt_emit_string = lt_emit_stringz;
506 	break;
507 
508 	case LT_ZMODE_BZIP2:
509 	lt->lt_emit_u8 = lt_emit_u8bz;
510 	lt->lt_emit_u16 = lt_emit_u16bz;
511 	lt->lt_emit_u24 = lt_emit_u24bz;
512 	lt->lt_emit_u32 = lt_emit_u32bz;
513 	lt->lt_emit_u64 = lt_emit_u64bz;
514 	lt->lt_emit_double = lt_emit_doublebz;
515 	lt->lt_emit_string = lt_emit_stringbz;
516 	break;
517 	}
518 }
519 
520 
521 /*
522  * hash/symtable manipulation
523  */
lt_hash(const char * s)524 static int lt_hash(const char *s)
525 {
526 const char *p;
527 char ch;
528 unsigned int h=0, h2=0, pos=0, g;
529 for(p=s;*p;p++)
530         {
531 	ch=*p;
532 	h2<<=3;
533 	h2-=((unsigned int)ch+(pos++));		/* this handles stranded vectors quite well.. */
534 
535         h=(h<<4)+ch;
536         if((g=h&0xf0000000))
537                 {
538                 h=h^(g>>24);
539                 h=h^g;
540                 }
541         }
542 
543 h^=h2;						/* combine the two hashes */
544 return(h%LT_SYMPRIME);
545 }
546 
547 
lt_symadd(struct lt_trace * lt,const char * name,int hv)548 static struct lt_symbol *lt_symadd(struct lt_trace *lt, const char *name, int hv)
549 {
550 struct lt_symbol *s;
551 
552 s=(struct lt_symbol *)calloc(1,sizeof(struct lt_symbol));
553 strcpy(s->name=(char *)malloc((s->namlen=strlen(name))+1),name);
554 s->next=lt->sym[hv];
555 lt->sym[hv]=s;
556 return(s);
557 }
558 
559 
lt_symfind(struct lt_trace * lt,const char * s)560 static struct lt_symbol *lt_symfind(struct lt_trace *lt, const char *s)
561 {
562 int hv;
563 struct lt_symbol *temp;
564 
565 hv=lt_hash(s);
566 if(!(temp=lt->sym[hv])) return(NULL); /* no hash entry, add here wanted to add */
567 
568 while(temp)
569         {
570         if(!strcmp(temp->name,s))
571                 {
572                 return(temp); /* in table already */
573                 }
574         if(!temp->next) break;
575         temp=temp->next;
576         }
577 
578 return(NULL); /* not found, add here if you want to add*/
579 }
580 
581 
582 /*
583  * compress facs to a prefix count + string + 0x00
584  */
lt_compress_fac(struct lt_trace * lt,char * str)585 static void lt_compress_fac(struct lt_trace *lt, char *str)
586 {
587 int i;
588 int len = strlen(str);
589 int minlen = (len<lt->compress_fac_len) ? len : lt->compress_fac_len;
590 
591 if(minlen>65535) minlen=65535;    /* keep in printable range--most hierarchies won't be this big anyway */
592 
593 if(lt->compress_fac_str)
594         {
595         for(i=0;i<minlen;i++)
596                 {
597                 if(lt->compress_fac_str[i]!=str[i]) break;
598                 }
599 	lt_emit_u16z(lt, i);
600 	lt_emit_stringz(lt, str+i);
601         free(lt->compress_fac_str);
602         }
603         else
604         {
605 	lt_emit_u16z(lt, 0);
606 	lt_emit_stringz(lt, str);
607         }
608 
609 lt->compress_fac_str = (char *) malloc((lt->compress_fac_len=len)+1);
610 strcpy(lt->compress_fac_str, str);
611 }
612 
613 
strip_brack(struct lt_symbol * s)614 static void strip_brack(struct lt_symbol *s)
615 {
616 char *lastch = s->name+s->namlen - 1;
617 if(*lastch!=']') return;
618 if(s->namlen<3) return;
619 lastch--;
620 while(lastch!=s->name)
621 	{
622 	if(*lastch=='.')
623 		{
624 		return;	/* MTI SV [0.3] notation for implicit vars */
625 		}
626 
627 	if(*lastch=='[')
628 		{
629 		*lastch=0x00;
630 		return;
631 		}
632 	lastch--;
633 	}
634 return;
635 }
636 
637 
lt_emitfacs(struct lt_trace * lt)638 static void lt_emitfacs(struct lt_trace *lt)
639 {
640 int i;
641 
642 if((lt)&&(lt->numfacs))
643 	{
644 	struct lt_symbol *s = lt->symchain;
645 	char is_interlaced_trace = (lt->sorted_facs==NULL);
646 
647 	if(!lt->sorted_facs)
648 		{
649 		if((lt->sorted_facs = (struct lt_symbol **)calloc(lt->numfacs, sizeof(struct lt_symbol *))))
650 			{
651 			if(lt->do_strip_brackets)
652 			for(i=0;i<lt->numfacs;i++)
653 				{
654 				lt->sorted_facs[lt->numfacs - i - 1] = s;	/* facs were chained backwards so reverse to restore bitslicing */
655 				strip_brack(s);
656 				s=s->symchain;
657 				}
658 			else
659 			for(i=0;i<lt->numfacs;i++)
660 				{
661 				lt->sorted_facs[lt->numfacs - i - 1] = s;	/* facs were chained backwards so reverse to restore bitslicing*/
662 				s=s->symchain;
663 				}
664 			wave_msort(lt->sorted_facs, lt->numfacs);
665 
666 			for(i=0;i<lt->numfacs;i++)
667 				{
668 				lt->sorted_facs[i]->facnum = i;
669 				}
670 			}
671 		}
672 
673 	if(lt->sorted_facs)
674 		{
675 		lt->facname_offset=lt->position;
676 
677 		lt_emit_u32(lt, lt->numfacs);		/* uncompressed */
678 		lt_emit_u32(lt, lt->numfacbytes);	/* uncompressed */
679 		fflush(lt->handle);
680 		lt->zfacname_size = lt->position;
681 		lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9");
682 
683 		lt->zpackcount = 0;
684 		for(i=0;i<lt->numfacs;i++)
685 			{
686 		 	lt_compress_fac(lt, lt->sorted_facs[i]->name);
687 			}
688 		free(lt->compress_fac_str); lt->compress_fac_str=NULL;
689 		lt->compress_fac_len=0;
690 		lt->zfacname_predec_size = lt->zpackcount;
691 
692 		gzclose(lt->zhandle);
693 		fseeko(lt->handle, 0L, SEEK_END);
694 		lt->position=ftello(lt->handle);
695 		lt->zfacname_size = lt->position - lt->zfacname_size;
696 
697 		lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9");
698 
699 		lt->facgeometry_offset = lt->position;
700 		for(i=0;i<lt->numfacs;i++)
701 			{
702 			if((lt->sorted_facs[i]->flags&LT_SYM_F_ALIAS)==0)
703 				{
704 				lt_emit_u32z(lt, lt->sorted_facs[i]->rows);
705 				lt_emit_u32z(lt, lt->sorted_facs[i]->msb);
706 				lt_emit_u32z(lt, lt->sorted_facs[i]->lsb);
707 				lt_emit_u32z(lt, lt->sorted_facs[i]->flags);
708 				}
709 				else
710 				{
711 				lt_emit_u32z(lt, lt->sorted_facs[i]->aliased_to->facnum);
712 				lt_emit_u32z(lt, lt->sorted_facs[i]->msb);
713 				lt_emit_u32z(lt, lt->sorted_facs[i]->lsb);
714 				lt_emit_u32z(lt, LT_SYM_F_ALIAS);
715 				}
716 			}
717 
718 		gzclose(lt->zhandle);
719 		fseeko(lt->handle, 0L, SEEK_END);
720 		lt->position=ftello(lt->handle);
721 		lt->zfacgeometry_size = lt->position - lt->facgeometry_offset;
722 
723 		if(is_interlaced_trace)
724 			{
725 			lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9");
726 
727 			lt->sync_table_offset = lt->position;
728 			for(i=0;i<lt->numfacs;i++)
729 				{
730 				lt_emit_u32z(lt, lt->sorted_facs[i]->last_change);
731 				}
732 
733 			gzclose(lt->zhandle); lt->zhandle = NULL;
734 			fseeko(lt->handle, 0L, SEEK_END);
735 			lt->position=ftello(lt->handle);
736 			lt->zsync_table_size = lt->position - lt->sync_table_offset;
737 			}
738 		}
739 	}
740 }
741 
742 
743 /*
744  * initialize the trace and get back an lt context
745  */
lt_init(const char * name)746 struct lt_trace *lt_init(const char *name)
747 {
748 struct lt_trace *lt=(struct lt_trace *)calloc(1, sizeof(struct lt_trace));
749 
750 if(!(lt->handle=fopen(name, "wb")))
751 	{
752 	free(lt);
753 	lt=NULL;
754 	}
755 	else
756 	{
757 	lt_emit_u16(lt, LT_HDRID);
758 	lt_emit_u16(lt, LT_VERSION);
759 	lt->change_field_offset = lt->position;
760 	lt->initial_value = -1;				/* if a user sets this it will have a different POSITIVE val */
761 	lt->timescale = -256;				/* will be in range of -128<=x<=127 if set */
762 
763 	lt_set_zmode(lt, LT_ZMODE_NONE);
764 
765 	lt->mintime=ULLDescriptor(1);
766 	lt->maxtime=ULLDescriptor(0);
767 	}
768 
769 return(lt);
770 }
771 
772 /*
773  * clock flushing..
774  */
lt_flushclock(struct lt_trace * lt,struct lt_symbol * s)775 static void lt_flushclock(struct lt_trace *lt, struct lt_symbol *s)
776 {
777 unsigned int last_change_delta = lt->position - s->last_change - 2;
778 unsigned int start_position = lt->position;
779 int tag;
780 int numbytes, numbytes_trans;
781 int numtrans = s->clk_numtrans - LT_CLKPACK - 1;
782 
783 if(numtrans<0)
784 	{
785 	/* it never got around to caching */
786 	fprintf(stderr, "Possible Problem with %s with %d?\n", s->name, s->clk_numtrans);
787 	return;
788 	}
789 
790 if(numtrans >= 256*65536)
791 	{
792 	numbytes_trans = 3;
793 	}
794 else
795 if(numtrans >= 65536)
796 	{
797 	numbytes_trans = 2;
798 	}
799 else
800 if(numtrans >= 256)
801 	{
802 	numbytes_trans = 1;
803 	}
804 else
805 	{
806 	numbytes_trans = 0;
807 	}
808 
809 if(!lt->numfacs_bytes)
810 	{
811 	if(last_change_delta >= 256*65536)
812 		{
813 		numbytes = 3;
814 		}
815 	else
816 	if(last_change_delta >= 65536)
817 		{
818 		numbytes = 2;
819 		}
820 	else
821 	if(last_change_delta >= 256)
822 		{
823 		numbytes = 1;
824 		}
825 	else
826 		{
827 		numbytes = 0;
828 		}
829 
830 	tag = (numbytes<<4) + 0xC + numbytes_trans;	/* yields xC..xF */
831 
832 	lt->lt_emit_u8(lt, tag);
833 	switch(numbytes&3)
834 		{
835 		case 0: lt->lt_emit_u8(lt, last_change_delta); break;
836 		case 1: lt->lt_emit_u16(lt, last_change_delta); break;
837 		case 2: lt->lt_emit_u24(lt, last_change_delta); break;
838 		case 3: lt->lt_emit_u32(lt, last_change_delta); break;
839 		}
840 	}
841 	else
842 	{
843 	tag = 0xC + numbytes_trans;	/* yields C..F */
844 
845 	switch(lt->numfacs_bytes)
846 		{
847 		case 1: lt->lt_emit_u8(lt, s->facnum); break;
848 		case 2: lt->lt_emit_u16(lt, s->facnum); break;
849 		case 3: lt->lt_emit_u24(lt, s->facnum); break;
850 		case 4: lt->lt_emit_u32(lt, s->facnum); break;
851 		}
852 	lt->lt_emit_u8(lt, tag);
853 	}
854 
855 s->last_change = start_position;
856 
857 /* s->clk_prevval		CAN BE INFERRED! */
858 /* s->clk_prevtrans		CAN BE INFERRED! */
859 /* s->clk_delta 		CAN BE INFERRED! */
860 
861 switch(numbytes_trans&3)
862 	{
863 	case 0: lt->lt_emit_u8(lt, numtrans); break;
864 	case 1: lt->lt_emit_u16(lt, numtrans); break;
865 	case 2: lt->lt_emit_u24(lt, numtrans); break;
866 	case 3: lt->lt_emit_u32(lt, numtrans); break;
867 	}
868 
869 /* printf("Clock finish for '%s' at %lld ending with '%c' for %d repeats over a switch delta of %d\n",
870 	s->name, lt->timeval, s->clk_prevval, s->clk_numtrans - LT_CLKPACK, s->clk_delta); */
871 s->clk_prevtrans = ULLDescriptor(~0);
872 s->clk_numtrans = 0;
873 }
874 
lt_flushclock_m(struct lt_trace * lt,struct lt_symbol * s)875 static void lt_flushclock_m(struct lt_trace *lt, struct lt_symbol *s)
876 {
877 unsigned int last_change_delta = lt->position - s->last_change - 2;
878 unsigned int start_position = lt->position;
879 int tag;
880 int numbytes, numbytes_trans;
881 int numtrans = s->clk_numtrans - LT_CLKPACK_M - 1;
882 
883 if(numtrans<0)
884 	{
885 	/* it never got around to caching */
886 	fprintf(stderr, "Possible Problem with %s with %d?\n", s->name, s->clk_numtrans);
887 	return;
888 	}
889 
890 if(numtrans >= 256*65536)
891 	{
892 	numbytes_trans = 3;
893 	}
894 else
895 if(numtrans >= 65536)
896 	{
897 	numbytes_trans = 2;
898 	}
899 else
900 if(numtrans >= 256)
901 	{
902 	numbytes_trans = 1;
903 	}
904 else
905 	{
906 	numbytes_trans = 0;
907 	}
908 
909 if(!lt->numfacs_bytes)
910 	{
911 	if(last_change_delta >= 256*65536)
912 		{
913 		numbytes = 3;
914 		}
915 	else
916 	if(last_change_delta >= 65536)
917 		{
918 		numbytes = 2;
919 		}
920 	else
921 	if(last_change_delta >= 256)
922 		{
923 		numbytes = 1;
924 		}
925 	else
926 	{
927 	numbytes = 0;
928 	}
929 
930 	tag = (numbytes<<4) + 0xC + numbytes_trans;	/* yields xC..xF */
931 
932 	lt->lt_emit_u8(lt, tag);
933 	switch(numbytes&3)
934 		{
935 		case 0: lt->lt_emit_u8(lt, last_change_delta); break;
936 		case 1: lt->lt_emit_u16(lt, last_change_delta); break;
937 		case 2: lt->lt_emit_u24(lt, last_change_delta); break;
938 		case 3: lt->lt_emit_u32(lt, last_change_delta); break;
939 		}
940 	}
941 	else
942 	{
943 	tag = 0xC + numbytes_trans;	/* yields C..F */
944 
945 	switch(lt->numfacs_bytes)
946 		{
947 		case 1: lt->lt_emit_u8(lt, s->facnum); break;
948 		case 2: lt->lt_emit_u16(lt, s->facnum); break;
949 		case 3: lt->lt_emit_u24(lt, s->facnum); break;
950 		case 4: lt->lt_emit_u32(lt, s->facnum); break;
951 		}
952 	lt->lt_emit_u8(lt, tag);
953 	}
954 
955 
956 s->last_change = start_position;
957 
958 /* s->clk_prevval		CAN BE INFERRED! */
959 /* s->clk_prevtrans		CAN BE INFERRED! */
960 /* s->clk_delta 		CAN BE INFERRED! */
961 
962 switch(numbytes_trans&3)
963 	{
964 	case 0: lt->lt_emit_u8(lt, numtrans); break;
965 	case 1: lt->lt_emit_u16(lt, numtrans); break;
966 	case 2: lt->lt_emit_u24(lt, numtrans); break;
967 	case 3: lt->lt_emit_u32(lt, numtrans); break;
968 	}
969 
970 /* printf("Clock finish for '%s' at %lld ending with '%08x' for %d repeats over a switch delta of %lld\n",
971 	s->name, lt->timeval, s->clk_prevval, s->clk_numtrans - LT_CLKPACK_M, s->clk_delta); */
972 s->clk_prevtrans = ULLDescriptor(~0);
973 s->clk_numtrans = 0;
974 }
975 
976 
977 /*
978  * recurse through dictionary
979  */
lt_recurse_dictionary(struct lt_trace * lt,dslxt_Tree * ds)980 static void lt_recurse_dictionary(struct lt_trace *lt, dslxt_Tree *ds)
981 {
982 if(ds->left) lt_recurse_dictionary(lt, ds->left);
983 lt->sorted_dict[ds->val] = ds;
984 if(ds->right) lt_recurse_dictionary(lt, ds->right);
985 }
986 
lt_recurse_dictionary_free(struct lt_trace * lt,dslxt_Tree * ds)987 static void lt_recurse_dictionary_free(struct lt_trace *lt, dslxt_Tree *ds)
988 {
989 dslxt_Tree *lft = ds->left;
990 dslxt_Tree *rgh = ds->right;
991 
992 if(lft) lt_recurse_dictionary_free(lt, lft);
993 free(ds->item); free(ds);
994 if(rgh) lt_recurse_dictionary_free(lt, rgh);
995 }
996 
lt_dictval_compare(const void * v1,const void * v2)997 static int lt_dictval_compare(const void *v1, const void *v2)
998 {
999 const dslxt_Tree *s1 = *(const dslxt_Tree * const *)v1;
1000 const dslxt_Tree *s2 = *(const dslxt_Tree * const *)v2;
1001 
1002 if(s1->val > s2->val) return(1); else return(-1);	/* they're *never* equal */
1003 }
1004 
lt_finalize_dictionary(struct lt_trace * lt)1005 static void lt_finalize_dictionary(struct lt_trace *lt)
1006 {
1007 unsigned int i;
1008 
1009 lt->sorted_dict = calloc(lt->num_dict_entries, sizeof(dslxt_Tree *));
1010 
1011 lt->dictionary_offset=lt->position;
1012 
1013 lt_emit_u32(lt, lt->num_dict_entries);		/* uncompressed */
1014 lt_emit_u32(lt, lt->dict_string_mem_required - lt->num_dict_entries);	/* uncompressed : minus because leading '1' is implied so its stripped */
1015 lt_emit_u32(lt, lt->dict16_offset);		/* uncompressed */
1016 lt_emit_u32(lt, lt->dict24_offset);		/* uncompressed */
1017 lt_emit_u32(lt, lt->dict32_offset);		/* uncompressed */
1018 lt_emit_u32(lt, lt->mindictwidth);		/* uncompressed */
1019 fflush(lt->handle);
1020 
1021 #if 0
1022 fprintf(stderr, "*** dictionary_offset = %08x\n", lt->dictionary_offset);
1023 fprintf(stderr, "*** num_dict_entries = %d\n", lt->num_dict_entries);
1024 #endif
1025 
1026 lt->zdictionary_size = lt->position;
1027 lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9");
1028 
1029 lt_recurse_dictionary(lt, lt->dict);
1030 qsort((void *)lt->sorted_dict, lt->num_dict_entries, sizeof(struct dsTree **), lt_dictval_compare);
1031 
1032 for(i=0;i<lt->num_dict_entries;i++)
1033 	{
1034 	dslxt_Tree *ds = lt->sorted_dict[i];
1035 	/* fprintf(stderr, "%8d) '%s'\n", ds->val, ds->item); */
1036 	lt_emit_stringz(lt, ds->item+1);
1037 	}
1038 
1039 gzclose(lt->zhandle);
1040 fseeko(lt->handle, 0L, SEEK_END);
1041 lt->position=ftello(lt->handle);
1042 lt->zdictionary_size = lt->position - lt->zdictionary_size;
1043 
1044 free(lt->sorted_dict); lt->sorted_dict = NULL;
1045 
1046 lt_recurse_dictionary_free(lt, lt->dict);
1047 lt->dict = NULL;
1048 }
1049 
1050 
1051 /*
1052  * close out the trace and fixate it
1053  */
lt_close(struct lt_trace * lt)1054 void lt_close(struct lt_trace *lt)
1055 {
1056 lxttime_t lasttime=ULLDescriptor(0);
1057 int lastposition=0;
1058 char is64=0;
1059 
1060 if(lt)
1061 	{
1062 	struct lt_symbol *s = lt->symchain;
1063 
1064 	if(lt->clock_compress)
1065 	while(s)
1066 		{
1067                if(s->clk_prevtrans!=ULLDescriptor(~0))
1068                         {
1069                         int len = ((s->flags)&LT_SYM_F_INTEGER) ? 32 : s->len;
1070                         if(len>1)
1071                                 {
1072                                 if(s->clk_numtrans > LT_CLKPACK_M) lt_flushclock_m(lt, s);
1073                                 }
1074                                 else
1075                                 {
1076                                 if(s->clk_numtrans > LT_CLKPACK) lt_flushclock(lt, s);
1077                                 }
1078                         }
1079 
1080                 s=s->symchain;
1081 		}
1082 
1083 	lt_set_dumpon(lt);	/* in case it was turned off */
1084 
1085 	if(lt->zmode!=LT_ZMODE_NONE)
1086 		{
1087 		lt->chg_table_size = lt->position - lt->change_field_offset;
1088 
1089 		switch(lt->zmode)
1090 			{
1091 			case LT_ZMODE_GZIP: 	gzclose(lt->zhandle); break;
1092 			case LT_ZMODE_BZIP2:	BZ2_bzclose(lt->zhandle); break;
1093 			}
1094 		lt->zhandle = NULL;
1095 		fseeko(lt->handle, 0L, SEEK_END);
1096 		lt->position=ftello(lt->handle);
1097 
1098 		lt_set_zmode(lt, LT_ZMODE_NONE);
1099 		lt->zchg_table_size = lt->position - lt->change_field_offset;
1100 		}
1101 
1102 	lt_emitfacs(lt);
1103 	if(lt->dict) lt_finalize_dictionary(lt);
1104 
1105 	free(lt->timebuff);
1106 	lt->timebuff=NULL;
1107 
1108 	if(lt->timehead)
1109 		{
1110 		struct lt_timetrail *t=lt->timehead;
1111 		struct lt_timetrail *t2;
1112 
1113 		lt->time_table_offset = lt->position;
1114 
1115 		lt_emit_u32(lt, lt->timechangecount);	/* this is uncompressed! */
1116 
1117 		fflush(lt->handle);
1118 		lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9");
1119 		lt->ztime_table_size = lt->position;
1120 
1121 		is64=(lt->maxtime > ULLDescriptor(0xFFFFFFFF));
1122 
1123 		if(is64)
1124 			{
1125 			lt_emit_u64z(lt, (int)((lt->mintime)>>32), (int)lt->mintime);
1126 			lt_emit_u64z(lt, (int)((lt->maxtime)>>32), (int)lt->maxtime);
1127 			}
1128 			else
1129 			{
1130 			lt_emit_u32z(lt, (int)lt->mintime);
1131 			lt_emit_u32z(lt, (int)lt->maxtime);
1132 			}
1133 
1134 		while(t)
1135 			{
1136 			lt_emit_u32z(lt, t->position - lastposition); lastposition = t->position;
1137 			t=t->next;
1138 			}
1139 
1140 		t=lt->timehead;
1141 		if(is64)
1142 			{
1143 			while(t)
1144 				{
1145 				lxttime_t delta = t->timeval - lasttime;
1146 				lt_emit_u64z(lt, (int)(delta>>32), (int)delta); lasttime = t->timeval;
1147 
1148 				t2=t->next;
1149 				free(t);
1150 				t=t2;
1151 				}
1152 			}
1153 		else
1154 			{
1155 			while(t)
1156 				{
1157 				lt_emit_u32z(lt, (int)(t->timeval - lasttime)); lasttime = t->timeval;
1158 
1159 				t2=t->next;
1160 				free(t);
1161 				t=t2;
1162 				}
1163 
1164 			lt->timehead = lt->timecurr = NULL;
1165 			}
1166 
1167 		gzclose(lt->zhandle); lt->zhandle = NULL;
1168 		fseeko(lt->handle, 0L, SEEK_END);
1169 		lt->position=ftello(lt->handle);
1170 		lt->ztime_table_size = lt->position - lt->ztime_table_size;
1171 		}
1172 
1173 	if(lt->initial_value>=0)
1174 		{
1175 		lt->initial_value_offset = lt->position;
1176 		lt_emit_u8(lt, lt->initial_value);
1177 		}
1178 
1179 	if((lt->timescale>-129)&&(lt->timescale<128))
1180 		{
1181 		lt->timescale_offset = lt->position;
1182 		lt_emit_u8(lt, lt->timescale);
1183 		}
1184 
1185 	if(lt->double_used)
1186 		{
1187 		lt->double_test_offset = lt->position;
1188 		lt_emit_double(lt, 3.14159);
1189 		}
1190 
1191 	if(lt->dumpoffcount)
1192 		{
1193 		struct lt_timetrail *ltt = lt->dumpoffhead;
1194 		struct lt_timetrail *ltt2;
1195 
1196 		lt->exclude_offset = lt->position;
1197 		lt_emit_u32(lt, lt->dumpoffcount);
1198 
1199 		while(ltt)
1200 			{
1201 			lt_emit_u64(lt, (int)((ltt->timeval)>>32), (int)ltt->timeval);
1202 			ltt2 = ltt;
1203 			ltt=ltt->next;
1204 			free(ltt2);
1205 			}
1206 
1207 		lt->dumpoffhead = lt->dumpoffcurr = NULL;
1208 		lt->dumpoffcount = 0;
1209 		}
1210 
1211 	if(lt->timezero)
1212 		{
1213 		lt->timezero_offset = lt->position;
1214 		lt_emit_u64(lt, (int)((lt->timezero)>>32), (int)lt->timezero);
1215 		}
1216 
1217 	/* prefix */
1218 	lt_emit_u8(lt, LT_SECTION_END);
1219 
1220 	/* Version 1 */
1221 	if(lt->change_field_offset) { lt_emit_u32(lt, lt->change_field_offset); lt_emit_u8(lt, LT_SECTION_CHG); lt->change_field_offset = 0; }
1222 	if(lt->sync_table_offset) { lt_emit_u32(lt, lt->sync_table_offset); lt_emit_u8(lt, LT_SECTION_SYNC_TABLE); lt->sync_table_offset = 0; }
1223 	if(lt->facname_offset) { lt_emit_u32(lt, lt->facname_offset); lt_emit_u8(lt, LT_SECTION_FACNAME); lt->facname_offset = 0; }
1224 	if(lt->facgeometry_offset) { lt_emit_u32(lt, lt->facgeometry_offset); lt_emit_u8(lt, LT_SECTION_FACNAME_GEOMETRY); lt->facgeometry_offset = 0; }
1225 	if(lt->timescale_offset) { lt_emit_u32(lt, lt->timescale_offset); lt_emit_u8(lt, LT_SECTION_TIMESCALE); lt->timescale_offset = 0; }
1226 	if(lt->time_table_offset) { lt_emit_u32(lt, lt->time_table_offset); lt_emit_u8(lt, is64 ? LT_SECTION_TIME_TABLE64 : LT_SECTION_TIME_TABLE); lt->time_table_offset = 0; }
1227 	if(lt->initial_value_offset) { lt_emit_u32(lt, lt->initial_value_offset); lt_emit_u8(lt, LT_SECTION_INITIAL_VALUE); lt->initial_value_offset = 0; }
1228 	if(lt->double_test_offset) { lt_emit_u32(lt, lt->double_test_offset); lt_emit_u8(lt, LT_SECTION_DOUBLE_TEST); lt->double_test_offset = 0; }
1229 
1230 	/* Version 2 adds */
1231 	if(lt->zfacname_predec_size) { lt_emit_u32(lt, lt->zfacname_predec_size); lt_emit_u8(lt, LT_SECTION_ZFACNAME_PREDEC_SIZE); lt->zfacname_predec_size = 0; }
1232 	if(lt->zfacname_size) { lt_emit_u32(lt, lt->zfacname_size); lt_emit_u8(lt, LT_SECTION_ZFACNAME_SIZE); lt->zfacname_size = 0; }
1233 	if(lt->zfacgeometry_size) { lt_emit_u32(lt, lt->zfacgeometry_size); lt_emit_u8(lt, LT_SECTION_ZFACNAME_GEOMETRY_SIZE); lt->zfacgeometry_size = 0; }
1234 	if(lt->zsync_table_size) { lt_emit_u32(lt, lt->zsync_table_size); lt_emit_u8(lt, LT_SECTION_ZSYNC_SIZE); lt->zsync_table_size = 0; }
1235 	if(lt->ztime_table_size) { lt_emit_u32(lt, lt->ztime_table_size); lt_emit_u8(lt, LT_SECTION_ZTIME_TABLE_SIZE); lt->ztime_table_size = 0; }
1236 	if(lt->chg_table_size) { lt_emit_u32(lt, lt->chg_table_size); lt_emit_u8(lt, LT_SECTION_ZCHG_PREDEC_SIZE); lt->chg_table_size = 0; }
1237 	if(lt->zchg_table_size) { lt_emit_u32(lt, lt->zchg_table_size); lt_emit_u8(lt, LT_SECTION_ZCHG_SIZE); lt->zchg_table_size = 0; }
1238 
1239 	/* Version 4 adds */
1240 	if(lt->dictionary_offset) { lt_emit_u32(lt, lt->dictionary_offset); lt_emit_u8(lt, LT_SECTION_ZDICTIONARY); lt->dictionary_offset = 0; }
1241 	if(lt->zdictionary_size) { lt_emit_u32(lt, lt->zdictionary_size); lt_emit_u8(lt, LT_SECTION_ZDICTIONARY_SIZE); lt->zdictionary_size = 0; }
1242 
1243 	/* Version 5 adds */
1244 	if(lt->exclude_offset) { lt_emit_u32(lt, lt->exclude_offset); lt_emit_u8(lt, LT_SECTION_EXCLUDE_TABLE); lt->exclude_offset = 0; }
1245 
1246 	/* Version 6 adds */
1247 	if(lt->timezero_offset) { lt_emit_u32(lt, lt->timezero_offset); lt_emit_u8(lt, LT_SECTION_TIMEZERO); lt->timezero_offset = 0; }
1248 
1249 	/* suffix */
1250 	lt_emit_u8(lt, LT_TRLID);
1251 
1252 	if(lt->symchain)
1253 		{
1254 		struct lt_symbol *sc = lt->symchain;
1255 		struct lt_symbol *s2;
1256 
1257 		while(sc)
1258 			{
1259 			free(sc->name);
1260 			s2=sc->symchain;
1261 			free(sc);
1262 			sc=s2;
1263 			}
1264 		}
1265 
1266 	free(lt->sorted_facs);
1267 	fclose(lt->handle);
1268 	free(lt);
1269 	}
1270 
1271 }
1272 
1273 
1274 /*
1275  * maint function for finding a symbol if it exists
1276  */
lt_symbol_find(struct lt_trace * lt,const char * name)1277 struct lt_symbol *lt_symbol_find(struct lt_trace *lt, const char *name)
1278 {
1279 struct lt_symbol *s=NULL;
1280 
1281 if((lt)&&(name)) s=lt_symfind(lt, name);
1282 return(s);
1283 }
1284 
1285 
1286 /*
1287  * add a trace (if it doesn't exist already)
1288  */
lt_symbol_add(struct lt_trace * lt,const char * name,unsigned int rows,int msb,int lsb,int flags)1289 struct lt_symbol *lt_symbol_add(struct lt_trace *lt, const char *name, unsigned int rows, int msb, int lsb, int flags)
1290 {
1291 struct lt_symbol *s;
1292 int len;
1293 int flagcnt;
1294 
1295 if((!lt)||(lt->sorted_facs)) return(NULL);
1296 
1297 flagcnt = ((flags&LT_SYM_F_INTEGER)!=0) + ((flags&LT_SYM_F_DOUBLE)!=0) + ((flags&LT_SYM_F_STRING)!=0);
1298 
1299 if((flagcnt>1)||(!lt)||(!name)||(lt_symfind(lt, name))) return (NULL);
1300 
1301 if(flags&LT_SYM_F_DOUBLE) lt->double_used = 1;
1302 
1303 s=lt_symadd(lt, name, lt_hash(name));
1304 s->rows = rows;
1305 s->flags = flags&(~LT_SYM_F_ALIAS);	/* aliasing makes no sense here.. */
1306 
1307 if(!flagcnt)
1308 	{
1309 	s->msb = msb;
1310 	s->lsb = lsb;
1311 	s->len = (msb<lsb) ? (lsb-msb+1) : (msb-lsb+1);
1312 
1313 	if((s->len==1)&&(s->rows==0)) s->clk_prevtrans = ULLDescriptor(~0);
1314 	}
1315 
1316 s->symchain = lt->symchain;
1317 lt->symchain = s;
1318 
1319 lt->numfacs++;
1320 
1321 if((len=strlen(name)) > lt->longestname) lt->longestname = len;
1322 lt->numfacbytes += (len+1);
1323 
1324 return(s);
1325 }
1326 
1327 /*
1328  * add an alias trace (if it doesn't exist already and orig is found)
1329  */
lt_symbol_alias(struct lt_trace * lt,const char * existing_name,const char * alias,int msb,int lsb)1330 struct lt_symbol *lt_symbol_alias(struct lt_trace *lt, const char *existing_name, const char *alias, int msb, int lsb)
1331 {
1332 struct lt_symbol *s, *sa;
1333 int len;
1334 int bitlen;
1335 int flagcnt;
1336 
1337 if((!lt)||(!existing_name)||(!alias)||(!(s=lt_symfind(lt, existing_name)))||(lt_symfind(lt, alias))) return (NULL);
1338 
1339 if(lt->sorted_facs) return(NULL);
1340 
1341 while(s->aliased_to)	/* find root alias */
1342 	{
1343 	s=s->aliased_to;
1344 	}
1345 
1346 flagcnt = ((s->flags&LT_SYM_F_INTEGER)!=0) + ((s->flags&LT_SYM_F_DOUBLE)!=0) + ((s->flags&LT_SYM_F_STRING)!=0);
1347 bitlen = (msb<lsb) ? (lsb-msb+1) : (msb-lsb+1);
1348 if((!flagcnt)&&(bitlen!=s->len)) return(NULL);
1349 
1350 sa=lt_symadd(lt, alias, lt_hash(alias));
1351 sa->flags = LT_SYM_F_ALIAS;	/* only point this can get set */
1352 sa->aliased_to = s;
1353 
1354 if(!flagcnt)
1355 	{
1356 	sa->msb = msb;
1357 	sa->lsb = lsb;
1358 	sa->len = bitlen;
1359 	}
1360 
1361 sa->symchain = lt->symchain;
1362 lt->symchain = sa;
1363 lt->numfacs++;
1364 if((len=strlen(alias)) > lt->longestname) lt->longestname = len;
1365 lt->numfacbytes += (len+1);
1366 
1367 return(sa);
1368 }
1369 
1370 
1371 /*
1372  * set current time
1373  */
lt_inc_time_by_delta(struct lt_trace * lt,unsigned int timeval)1374 int lt_inc_time_by_delta(struct lt_trace *lt, unsigned int timeval)
1375 {
1376 return(lt_set_time64(lt, lt->maxtime + (lxttime_t)timeval));
1377 }
1378 
lt_set_time(struct lt_trace * lt,unsigned int timeval)1379 int lt_set_time(struct lt_trace *lt, unsigned int timeval)
1380 {
1381 return(lt_set_time64(lt, (lxttime_t)timeval));
1382 }
1383 
lt_inc_time_by_delta64(struct lt_trace * lt,lxttime_t timeval)1384 int lt_inc_time_by_delta64(struct lt_trace *lt, lxttime_t timeval)
1385 {
1386 return(lt_set_time64(lt, lt->maxtime + timeval));
1387 }
1388 
lt_set_time64(struct lt_trace * lt,lxttime_t timeval)1389 int lt_set_time64(struct lt_trace *lt, lxttime_t timeval)
1390 {
1391 int rc=0;
1392 
1393 if(lt)
1394 	{
1395 	struct lt_timetrail *trl=(struct lt_timetrail *)calloc(1, sizeof(struct lt_timetrail));
1396 	if(trl)
1397 		{
1398 		trl->timeval = timeval;
1399 		trl->position = lt->position;
1400 
1401 		if((lt->timecurr)||(lt->timebuff))
1402 			{
1403 			if(((timeval>lt->mintime)&&(timeval>lt->maxtime))||((lt->mintime==ULLDescriptor(1))&&(lt->maxtime==ULLDescriptor(0))))
1404 				{
1405 				lt->maxtime = timeval;
1406 				}
1407 				else
1408 				{
1409 				free(trl);
1410 				goto bail;
1411 				}
1412 			}
1413 			else
1414 			{
1415 			lt->mintime = lt->maxtime = timeval;
1416 			}
1417 
1418 		free(lt->timebuff);
1419 		lt->timebuff = trl;
1420 		lt->timeval = timeval;
1421 		rc=1;
1422 		}
1423 	}
1424 
1425 bail:
1426 return(rc);
1427 }
1428 
1429 
1430 /*
1431  * sets trace timescale as 10**x seconds
1432  */
lt_set_timescale(struct lt_trace * lt,int timescale)1433 void lt_set_timescale(struct lt_trace *lt, int timescale)
1434 {
1435 if(lt)
1436 	{
1437 	lt->timescale = timescale;
1438 	}
1439 }
1440 
1441 
1442 /*
1443  * sets clock compression heuristic
1444  */
lt_set_clock_compress(struct lt_trace * lt)1445 void lt_set_clock_compress(struct lt_trace *lt)
1446 {
1447 if(lt)
1448 	{
1449 	lt->clock_compress = 1;
1450 	}
1451 }
1452 
1453 
1454 /*
1455  * sets change dump compression
1456  */
lt_set_chg_compress(struct lt_trace * lt)1457 void lt_set_chg_compress(struct lt_trace *lt)
1458 {
1459 if(lt)
1460 	{
1461 	if((lt->zmode==LT_ZMODE_NONE)&&(!lt->emitted))
1462 		{
1463 		lt_set_zmode(lt, lt->zmode = LT_ZMODE_GZIP);
1464 		fflush(lt->handle);
1465 		lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9");
1466 		}
1467 	}
1468 }
1469 
1470 
1471 /*
1472  * sets change dictionary compression
1473  */
lt_set_dict_compress(struct lt_trace * lt,unsigned int minwidth)1474 void lt_set_dict_compress(struct lt_trace *lt, unsigned int minwidth)
1475 {
1476 if((lt)&&(!lt->emitted))
1477 	{
1478 	lt->dictmode = 1;
1479 
1480 	if(minwidth>1)
1481 		{
1482 		lt->mindictwidth = minwidth;
1483 		}
1484 	}
1485 }
1486 
1487 /*
1488  * sets change interlace
1489  */
lt_set_no_interlace(struct lt_trace * lt)1490 void lt_set_no_interlace(struct lt_trace *lt)
1491 {
1492 if((lt)&&(!lt->emitted)&&(!lt->sorted_facs))
1493 	{
1494 	if(lt->zmode==LT_ZMODE_NONE)		/* this mode implies BZIP2 compression! */
1495 		{
1496 		lt_set_zmode(lt, lt->zmode = LT_ZMODE_BZIP2);
1497 		fflush(lt->handle);
1498 		lt->zhandle = BZ2_bzdopen(dup(fileno(lt->handle)), "wb9");
1499 		}
1500 
1501 	if((lt->sorted_facs = (struct lt_symbol **)calloc(lt->numfacs, sizeof(struct lt_symbol *))))
1502 		{
1503 		struct lt_symbol *s = lt->symchain;
1504 		int i;
1505 
1506 		if(lt->do_strip_brackets)
1507 		for(i=0;i<lt->numfacs;i++)
1508 			{
1509 			lt->sorted_facs[lt->numfacs - i - 1] = s;	/* facs were chained backwards so reverse to restore bitslicing */
1510 			strip_brack(s);
1511 			s=s->symchain;
1512 			}
1513 		else
1514 		for(i=0;i<lt->numfacs;i++)
1515 			{
1516 			lt->sorted_facs[lt->numfacs - i - 1] = s;	/* facs were chained backwards so reverse to restore bitslicing */
1517 			s=s->symchain;
1518 			}
1519 		wave_msort(lt->sorted_facs, lt->numfacs);
1520 
1521 		for(i=0;i<lt->numfacs;i++)
1522 			{
1523 			lt->sorted_facs[i]->facnum = i;
1524 			}
1525 
1526 		if(lt->numfacs >= 256*65536)
1527 			{
1528 			lt->numfacs_bytes = 4;
1529 			}
1530 		else
1531 		if(lt->numfacs >= 65536)
1532 			{
1533 			lt->numfacs_bytes = 3;
1534 			}
1535 		else
1536 		if(lt->numfacs >= 256)
1537 			{
1538 			lt->numfacs_bytes = 2;
1539 			}
1540 		else
1541 			{
1542 			lt->numfacs_bytes = 1;
1543 			}
1544 		}
1545 	}
1546 }
1547 
1548 
1549 /*
1550  * sets trace initial value
1551  */
lt_set_initial_value(struct lt_trace * lt,char value)1552 void lt_set_initial_value(struct lt_trace *lt, char value)
1553 {
1554 if(lt)
1555 	{
1556 	int tag;
1557 	switch(value)
1558 		{
1559 		case '0':	tag = 0; break;
1560 		case '1':	tag = 1; break;
1561 		case 'Z':
1562 		case 'z':	tag = 2; break;
1563 		case 'X':
1564 		case 'x':	tag = 3; break;
1565 		case 'H':
1566 		case 'h':	tag = 4; break;
1567 		case 'U':
1568 		case 'u':	tag = 5; break;
1569 		case 'W':
1570 		case 'w':	tag = 6; break;
1571 		case 'L':
1572 		case 'l':	tag = 0x7; break;
1573 		case '-':	tag = 0x8; break;
1574 		default:	tag = -1;  break;
1575 		}
1576 	lt->initial_value = tag;
1577 	}
1578 }
1579 
1580 
1581 /*
1582  * Sets bracket stripping (useful for VCD conversions of
1583  * bitblasted nets)
1584  */
lt_symbol_bracket_stripping(struct lt_trace * lt,int doit)1585 void lt_symbol_bracket_stripping(struct lt_trace *lt, int doit)
1586 {
1587 if(lt)
1588 	{
1589 	lt->do_strip_brackets = (doit!=0);
1590 	}
1591 }
1592 
1593 
1594 /*
1595  * emission for trace values..
1596  */
1597 static int lt_optimask[]=
1598 {
1599 0x00000000,
1600 
1601 0x00000001,
1602 0x00000003,
1603 0x00000007,
1604 0x0000000f,
1605 
1606 0x0000001f,
1607 0x0000003f,
1608 0x0000007f,
1609 0x000000ff,
1610 
1611 0x000001ff,
1612 0x000003ff,
1613 0x000007ff,
1614 0x00000fff,
1615 
1616 0x00001fff,
1617 0x00003fff,
1618 0x00007fff,
1619 0x0000ffff,
1620 
1621 0x0001ffff,
1622 0x0003ffff,
1623 0x0007ffff,
1624 0x000fffff,
1625 
1626 0x001fffff,
1627 0x003fffff,
1628 0x007fffff,
1629 0x00ffffff,
1630 
1631 0x01ffffff,
1632 0x03ffffff,
1633 0x07ffffff,
1634 0x0fffffff,
1635 
1636 0x1fffffff,
1637 0x3fffffff,
1638 0x7fffffff,
1639 0xffffffff
1640 };
1641 
1642 
lt_expand_integer_to_bits(int len,int value)1643 static char *lt_expand_integer_to_bits(int len, int value)
1644 {
1645 static char s[33];
1646 char *p = s;
1647 int i;
1648 
1649 len--;
1650 
1651 for(i=0;i<=len;i++)
1652 	{
1653 	*(p++) = '0' | ((value & (1<<(len-i)))!=0);
1654 	}
1655 *p = 0;
1656 
1657 return(s);
1658 }
1659 
1660 
lt_emit_value_int(struct lt_trace * lt,struct lt_symbol * s,unsigned int row,int value)1661 int lt_emit_value_int(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, int value)
1662 {
1663 int rc=0;
1664 
1665 if((!lt)||(!s)) return(rc);
1666 
1667 if(!lt->emitted) lt->emitted = 1;
1668 
1669 while(s->aliased_to)	/* find root alias if exists */
1670 	{
1671 	s=s->aliased_to;
1672 	}
1673 
1674 if(!(s->flags&(LT_SYM_F_DOUBLE|LT_SYM_F_STRING)))
1675 	{
1676 	int numbytes;				/* number of bytes to store value minus one */
1677 	unsigned int len = ((s->flags)&LT_SYM_F_INTEGER) ? 32 : s->len;
1678 	unsigned int last_change_delta;
1679 
1680 	if((lt->clock_compress)&&(s->rows==0))
1681 	{
1682 	if((len>1)&&(len<=32))
1683 		{
1684 		int ivalue = value;
1685 		int delta1, delta2;
1686 		s->clk_mask <<= 1;
1687 		s->clk_mask |= 1;
1688 
1689 		if(     ((s->clk_mask&0x1f)==0x1f) &&
1690 			( (delta1=(ivalue         - s->clk_prevval1) & lt_optimask[s->len]) == ((s->clk_prevval1 - s->clk_prevval3) & lt_optimask[s->len]) ) &&
1691 			( (delta2=(s->clk_prevval - s->clk_prevval2) & lt_optimask[s->len]) == ((s->clk_prevval2 - s->clk_prevval4) & lt_optimask[s->len]) ) &&
1692 			( (delta1==delta2) || ((!delta1)&&(!delta2)) )
1693 			)
1694 			{
1695 			if(s->clk_prevtrans==ULLDescriptor(~0))
1696 				{
1697 				s->clk_prevtrans = lt->timeval;
1698 				s->clk_numtrans = 0;
1699 				}
1700 			else
1701 			if(s->clk_numtrans == 0)
1702 				{
1703 				s->clk_delta = lt->timeval - s->clk_prevtrans;
1704 				s->clk_prevtrans = lt->timeval;
1705 				s->clk_numtrans++;
1706 				}
1707 			else
1708 				{
1709 				if(s->clk_delta == (lt->timeval - s->clk_prevtrans))
1710 					{
1711 					s->clk_numtrans++;
1712 					s->clk_prevtrans = lt->timeval;
1713 					if(s->clk_numtrans > LT_CLKPACK_M)
1714 						{
1715 						s->clk_prevval4 = s->clk_prevval3;
1716 						s->clk_prevval3 = s->clk_prevval2;
1717 						s->clk_prevval2 = s->clk_prevval1;
1718 						s->clk_prevval1 = s->clk_prevval;
1719 						s->clk_prevval  = ivalue;
1720 
1721 						/* printf("Clock value '%08x' for '%s' at %lld (#%d)\n", ivalue, s->name, lt->timeval, s->clk_numtrans); */
1722 						return(1);
1723 						}
1724 					}
1725 					else
1726 					{
1727 					if(s->clk_numtrans > LT_CLKPACK_M)
1728 						{
1729 						lt_flushclock_m(lt, s);
1730 						/* flush clock then continue below! */
1731 						}
1732 						else
1733 						{
1734 						s->clk_prevtrans=ULLDescriptor(~0);
1735 						}
1736 					}
1737 				}
1738 
1739 			}
1740 			else
1741 			{
1742 			if(s->clk_numtrans > LT_CLKPACK_M)
1743 				{
1744 				lt_flushclock_m(lt, s);
1745 				/* flush clock then continue below! */
1746 				}
1747 				else
1748 				{
1749 				s->clk_prevtrans=ULLDescriptor(~0);
1750 				}
1751 			}
1752 
1753 		s->clk_prevval4 = s->clk_prevval3;
1754 		s->clk_prevval3 = s->clk_prevval2;
1755 		s->clk_prevval2 = s->clk_prevval1;
1756 		s->clk_prevval1 = s->clk_prevval;
1757 		s->clk_prevval  = ivalue;
1758 		}
1759 	else
1760 	if(len==1) /* possible clock handling */
1761 		{
1762 		int ivalue = value&1;
1763 
1764 		if(((s->clk_prevval == '1') && (ivalue==0)) || ((s->clk_prevval == '0') && (ivalue==1)))
1765 			{
1766 			if(s->clk_prevtrans==ULLDescriptor(~0))
1767 				{
1768 				s->clk_prevtrans = lt->timeval;
1769 				s->clk_numtrans = 0;
1770 				}
1771 			else
1772 			if(s->clk_numtrans == 0)
1773 				{
1774 				s->clk_delta = lt->timeval - s->clk_prevtrans;
1775 				s->clk_prevtrans = lt->timeval;
1776 				s->clk_numtrans++;
1777 				}
1778 			else
1779 				{
1780 				if(s->clk_delta == (lt->timeval - s->clk_prevtrans))
1781 					{
1782 					s->clk_numtrans++;
1783 					s->clk_prevtrans = lt->timeval;
1784 					if(s->clk_numtrans > LT_CLKPACK)
1785 						{
1786 						s->clk_prevval = ivalue + '0';
1787 
1788 						/* printf("Clock value '%d' for '%s' at %d (#%d)\n", ivalue, s->name, lt->timeval, s->clk_numtrans); */
1789 						return(1);
1790 						}
1791 					}
1792 					else
1793 					{
1794 					if(s->clk_numtrans > LT_CLKPACK)
1795 						{
1796 						lt_flushclock(lt, s);
1797 						/* flush clock then continue below! */
1798 						}
1799 						else
1800 						{
1801 						s->clk_prevtrans=ULLDescriptor(~0);
1802 						}
1803 					}
1804 				}
1805 
1806 			}
1807 			else
1808 			{
1809 			if(s->clk_numtrans > LT_CLKPACK)
1810 				{
1811 				lt_flushclock(lt, s);
1812 				/* flush clock then continue below! */
1813 				}
1814 				else
1815 				{
1816 				s->clk_prevtrans=ULLDescriptor(~0);
1817 				}
1818 			}
1819 
1820 		s->clk_prevval = ivalue + '0';
1821 		}
1822 	}
1823 
1824 	/* normal trace handling */
1825 
1826 	last_change_delta = lt->position - s->last_change - 2;
1827 
1828 	if(last_change_delta >= 256*65536)
1829 		{
1830 		numbytes = 3;
1831 		}
1832 	else
1833 	if(last_change_delta >= 65536)
1834 		{
1835 		numbytes = 2;
1836 		}
1837 	else
1838 	if(last_change_delta >= 256)
1839 		{
1840 		numbytes = 1;
1841 		}
1842 	else
1843 		{
1844 		numbytes = 0;
1845 		}
1846 
1847 	if(len<=32)
1848 		{
1849 		int start_position = lt->position;
1850 		int tag;
1851 		int optimized0 = ((value&lt_optimask[len])==0);
1852 		int optimized1 = ((value&lt_optimask[len])==lt_optimask[len]);
1853 		int optimized  = optimized0|optimized1;
1854 
1855 		if(!lt->numfacs_bytes)
1856 			{
1857 			if(optimized)
1858 				{
1859 				tag = (numbytes<<4) | (3+optimized1);	/* for x3 and x4 cases */
1860 				}
1861 				else
1862 				{
1863 				tag = (numbytes<<4);
1864 				}
1865 
1866 			lt->lt_emit_u8(lt, tag);
1867 			switch(numbytes&3)
1868 				{
1869 				case 0: lt->lt_emit_u8(lt, last_change_delta); break;
1870 				case 1: lt->lt_emit_u16(lt, last_change_delta); break;
1871 				case 2: lt->lt_emit_u24(lt, last_change_delta); break;
1872 				case 3: lt->lt_emit_u32(lt, last_change_delta); break;
1873 				}
1874 			}
1875 			else
1876 			{
1877 			switch(lt->numfacs_bytes)
1878 				{
1879 				case 1: lt->lt_emit_u8(lt, s->facnum); break;
1880 				case 2: lt->lt_emit_u16(lt, s->facnum); break;
1881 				case 3: lt->lt_emit_u24(lt, s->facnum); break;
1882 				case 4: lt->lt_emit_u32(lt, s->facnum); break;
1883 				}
1884 			lt->lt_emit_u8(lt, optimized ? (3+optimized1) : 0);
1885 			}
1886 
1887 		s->last_change = start_position;
1888 
1889 		if(s->rows>0)
1890 			{
1891 			if(s->rows >= 256*65536)
1892 				{
1893 				numbytes = 3;
1894 				}
1895 			else
1896 			if(s->rows >= 65536)
1897 				{
1898 				numbytes = 2;
1899 				}
1900 			else
1901 			if(s->rows >= 256)
1902 				{
1903 				numbytes = 1;
1904 				}
1905 			else
1906 				{
1907 				numbytes = 0;
1908 				}
1909 
1910 			switch(numbytes&3)
1911 				{
1912 				case 0: lt->lt_emit_u8(lt, row); break;
1913 				case 1: lt->lt_emit_u16(lt, row); break;
1914 				case 2: lt->lt_emit_u24(lt, row); break;
1915 				case 3: lt->lt_emit_u32(lt, row); break;
1916 				}
1917 			}
1918 
1919 		if(!optimized)
1920 			{
1921 			if((lt->dictmode)&&(len>lt->mindictwidth))
1922 				{
1923 				char *vpnt_orig = lt_expand_integer_to_bits(len, value);
1924 				char *vpnt = vpnt_orig;
1925 
1926 				while ( (*vpnt == '0') && (*(vpnt+1)) ) vpnt++;
1927 
1928 				lt->dict = dslxt_splay (vpnt, lt->dict);
1929 				if(!dslxt_success)
1930 					{
1931 					unsigned int vlen = strlen(vpnt)+1;
1932 					char *vcopy = (char *)malloc(vlen);
1933 
1934 					strcpy(vcopy, vpnt);
1935 					lt->dict_string_mem_required += vlen;
1936 					lt->dict = dslxt_insert(vcopy, lt->dict, lt->num_dict_entries);
1937 
1938 					if(!lt->dict16_offset)
1939 						{
1940 						if(lt->num_dict_entries==256) lt->dict16_offset = lt->position;
1941 						}
1942 					else
1943 					if(!lt->dict24_offset)
1944 						{
1945 						if(lt->num_dict_entries==65536) lt->dict24_offset = lt->position;
1946 						}
1947 					else
1948 					if(!lt->dict32_offset)
1949 						{
1950 						if(lt->num_dict_entries==(256*65536)) lt->dict32_offset = lt->position;
1951 						}
1952 
1953 					lt->num_dict_entries++;
1954 					}
1955 
1956 				if(lt->dict24_offset)
1957 					{
1958 					if(lt->dict32_offset)
1959 						{
1960 						lt->lt_emit_u32(lt, lt->dict->val);
1961 						}
1962 						else
1963 						{
1964 						lt->lt_emit_u24(lt, lt->dict->val);
1965 						}
1966 					}
1967 				else
1968 					{
1969 					if(lt->dict16_offset)
1970 						{
1971 						lt->lt_emit_u16(lt, lt->dict->val);
1972 						}
1973 						else
1974 						{
1975 						lt->lt_emit_u8(lt, lt->dict->val);
1976 						}
1977 					}
1978 				}
1979 			else
1980 			if(len<9)
1981 				{
1982 				value <<= (8-len);
1983 				rc=lt->lt_emit_u8(lt, value);
1984 				}
1985 			else
1986 			if(len<17)
1987 				{
1988 				value <<= (16-len);
1989 				rc=lt->lt_emit_u16(lt, value);
1990 				}
1991 			else
1992 			if(len<25)
1993 				{
1994 				value <<= (24-len);
1995 				rc=lt->lt_emit_u24(lt, value);
1996 				}
1997 			else
1998 				{
1999 				value <<= (32-len);
2000 				rc=lt->lt_emit_u32(lt, value);
2001 				}
2002 			}
2003 		}
2004 
2005 	if(lt->timebuff)
2006 		{
2007 		lt->timechangecount++;
2008 		if(lt->timecurr)
2009 			{
2010 			lt->timecurr->next = lt->timebuff;
2011 			lt->timecurr = lt->timebuff;
2012 			}
2013 			else
2014 			{
2015 			lt->timehead = lt->timecurr = lt->timebuff;
2016 			}
2017 
2018 		lt->timebuff=NULL;
2019 		}
2020 	}
2021 
2022 return(rc);
2023 }
2024 
2025 
lt_emit_value_double(struct lt_trace * lt,struct lt_symbol * s,unsigned int row,double value)2026 int lt_emit_value_double(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, double value)
2027 {
2028 int rc=0;
2029 int start_position;
2030 int tag;
2031 
2032 if((!lt)||(!s)) return(rc);
2033 
2034 if(!lt->emitted) lt->emitted = 1;
2035 
2036 while(s->aliased_to)	/* find root alias if exists */
2037 	{
2038 	s=s->aliased_to;
2039 	}
2040 
2041 if((s->flags)&LT_SYM_F_DOUBLE)
2042 	{
2043 	int numbytes;				/* number of bytes to store value minus one */
2044 	unsigned int last_change_delta = lt->position - s->last_change - 2;
2045 
2046 	if(!lt->numfacs_bytes)
2047 		{
2048 		if(last_change_delta >= 256*65536)
2049 			{
2050 			numbytes = 3;
2051 			}
2052 		else
2053 		if(last_change_delta >= 65536)
2054 			{
2055 			numbytes = 2;
2056 			}
2057 		else
2058 		if(last_change_delta >= 256)
2059 			{
2060 			numbytes = 1;
2061 			}
2062 		else
2063 			{
2064 			numbytes = 0;
2065 			}
2066 
2067 		start_position = lt->position;
2068 		s->last_change = start_position;
2069 
2070 		tag = (numbytes<<4);
2071 		lt->lt_emit_u8(lt, tag);
2072 		switch(numbytes&3)
2073 			{
2074 			case 0: lt->lt_emit_u8(lt, last_change_delta); break;
2075 			case 1: lt->lt_emit_u16(lt, last_change_delta); break;
2076 			case 2: lt->lt_emit_u24(lt, last_change_delta); break;
2077 			case 3: lt->lt_emit_u32(lt, last_change_delta); break;
2078 			}
2079 		}
2080 		else
2081 		{
2082 		switch(lt->numfacs_bytes)
2083 			{
2084 			case 1: lt->lt_emit_u8(lt, s->facnum); break;
2085 			case 2: lt->lt_emit_u16(lt, s->facnum); break;
2086 			case 3: lt->lt_emit_u24(lt, s->facnum); break;
2087 			case 4: lt->lt_emit_u32(lt, s->facnum); break;
2088 			}
2089 		}
2090 
2091 	if(s->rows>0)
2092 		{
2093 		if(s->rows >= 256*65536)
2094 			{
2095 			numbytes = 3;
2096 			}
2097 		else
2098 		if(s->rows >= 65536)
2099 			{
2100 			numbytes = 2;
2101 			}
2102 		else
2103 		if(s->rows >= 256)
2104 			{
2105 			numbytes = 1;
2106 			}
2107 		else
2108 			{
2109 			numbytes = 0;
2110 			}
2111 
2112 		switch(numbytes&3)
2113 			{
2114 			case 0: lt->lt_emit_u8(lt, row); break;
2115 			case 1: lt->lt_emit_u16(lt, row); break;
2116 			case 2: lt->lt_emit_u24(lt, row); break;
2117 			case 3: lt->lt_emit_u32(lt, row); break;
2118 			}
2119 		}
2120 
2121 	rc=lt->lt_emit_double(lt, value);
2122 
2123 	if(lt->timebuff)
2124 		{
2125 		lt->timechangecount++;
2126 		if(lt->timecurr)
2127 			{
2128 			lt->timecurr->next = lt->timebuff;
2129 			lt->timecurr = lt->timebuff;
2130 			}
2131 			else
2132 			{
2133 			lt->timehead = lt->timecurr = lt->timebuff;
2134 			}
2135 
2136 		lt->timebuff=NULL;
2137 		}
2138 	}
2139 
2140 return(rc);
2141 }
2142 
2143 
lt_emit_value_string(struct lt_trace * lt,struct lt_symbol * s,unsigned int row,char * value)2144 int lt_emit_value_string(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, char *value)
2145 {
2146 int rc=0;
2147 int start_position;
2148 int tag;
2149 
2150 if((!lt)||(!s)||(!value)) return(rc);
2151 
2152 if(!lt->emitted) lt->emitted = 1;
2153 
2154 while(s->aliased_to)	/* find root alias if exists */
2155 	{
2156 	s=s->aliased_to;
2157 	}
2158 
2159 if((s->flags)&LT_SYM_F_STRING)
2160 	{
2161 	int numbytes;				/* number of bytes to store value minus one */
2162 	unsigned int last_change_delta = lt->position - s->last_change - 2;
2163 
2164 	if(!lt->numfacs_bytes)
2165 		{
2166 		if(last_change_delta >= 256*65536)
2167 			{
2168 			numbytes = 3;
2169 			}
2170 		else
2171 		if(last_change_delta >= 65536)
2172 			{
2173 			numbytes = 2;
2174 			}
2175 		else
2176 		if(last_change_delta >= 256)
2177 			{
2178 			numbytes = 1;
2179 			}
2180 		else
2181 			{
2182 			numbytes = 0;
2183 			}
2184 
2185 		start_position = lt->position;
2186 		s->last_change = start_position;
2187 
2188 		tag = (numbytes<<4);
2189 		lt->lt_emit_u8(lt, tag);
2190 		switch(numbytes&3)
2191 			{
2192 			case 0: lt->lt_emit_u8(lt, last_change_delta); break;
2193 			case 1: lt->lt_emit_u16(lt, last_change_delta); break;
2194 			case 2: lt->lt_emit_u24(lt, last_change_delta); break;
2195 			case 3: lt->lt_emit_u32(lt, last_change_delta); break;
2196 			}
2197 		}
2198 		else
2199 		{
2200 		switch(lt->numfacs_bytes)
2201 			{
2202 			case 1: lt->lt_emit_u8(lt, s->facnum); break;
2203 			case 2: lt->lt_emit_u16(lt, s->facnum); break;
2204 			case 3: lt->lt_emit_u24(lt, s->facnum); break;
2205 			case 4: lt->lt_emit_u32(lt, s->facnum); break;
2206 			}
2207 		}
2208 
2209 	if(s->rows>0)
2210 		{
2211 		if(s->rows >= 256*65536)
2212 			{
2213 			numbytes = 3;
2214 			}
2215 		else
2216 		if(s->rows >= 65536)
2217 			{
2218 			numbytes = 2;
2219 			}
2220 		else
2221 		if(s->rows >= 256)
2222 			{
2223 			numbytes = 1;
2224 			}
2225 		else
2226 			{
2227 			numbytes = 0;
2228 			}
2229 
2230 		switch(numbytes&3)
2231 			{
2232 			case 0: lt->lt_emit_u8(lt, row); break;
2233 			case 1: lt->lt_emit_u16(lt, row); break;
2234 			case 2: lt->lt_emit_u24(lt, row); break;
2235 			case 3: lt->lt_emit_u32(lt, row); break;
2236 			}
2237 		}
2238 
2239 	rc=lt->lt_emit_string(lt, value);
2240 
2241 	if(lt->timebuff)
2242 		{
2243 		lt->timechangecount++;
2244 		if(lt->timecurr)
2245 			{
2246 			lt->timecurr->next = lt->timebuff;
2247 			lt->timecurr = lt->timebuff;
2248 			}
2249 			else
2250 			{
2251 			lt->timehead = lt->timecurr = lt->timebuff;
2252 			}
2253 
2254 		lt->timebuff=NULL;
2255 		}
2256 	}
2257 
2258 return(rc);
2259 }
2260 
2261 
lt_emit_value_bit_string(struct lt_trace * lt,struct lt_symbol * s,unsigned int row,char * value)2262 int lt_emit_value_bit_string(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, char *value)
2263 {
2264 int rc=0;
2265 int start_position;
2266 int tag, tagadd;
2267 
2268 if((!lt)||(!s)||(!value)||(!*value)) return(rc);
2269 
2270 if(!lt->emitted) lt->emitted = 1;
2271 
2272 while(s->aliased_to)	/* find root alias if exists */
2273 	{
2274 	s=s->aliased_to;
2275 	}
2276 
2277 if(!(s->flags&(LT_SYM_F_DOUBLE|LT_SYM_F_STRING)))
2278 	{
2279 	int numbytes;				/* number of bytes to store value minus one */
2280 	char *pnt;
2281 	int mvl=0;
2282 	char ch;
2283 	char prevch;
2284 	unsigned int last_change_delta;
2285 
2286 	unsigned int len = ((s->flags)&LT_SYM_F_INTEGER) ? 32 : s->len;
2287 
2288 	if((lt->clock_compress)&&(s->rows==0))
2289 	{
2290 	if((len>1)&&(len<=32))
2291 		{
2292 		int legal = 0;
2293 		int ivalue = 0;
2294 		unsigned int i;
2295 		char *pntv = value;
2296 		int delta1, delta2;
2297 
2298 		for(i=0;i<len;i++)
2299 			{
2300 			if((*pntv!='0')&&(*pntv!='1'))
2301 				{
2302 				if((!*pntv)&&(i>0))
2303 					{
2304 					pntv--;
2305 					}
2306 					else
2307 					{
2308 					legal = 0;
2309 					break;
2310 					}
2311 				}
2312 
2313 			ivalue = (((unsigned int)ivalue) << 1);
2314 			ivalue |= (*pntv & 1);
2315 			legal = 1;
2316 			pntv++;
2317 			}
2318 		s->clk_mask <<= 1;
2319 		s->clk_mask |= legal;
2320 
2321 		if(     ((s->clk_mask&0x1f)==0x1f) &&
2322 			( (delta1=(ivalue         - s->clk_prevval1) & lt_optimask[s->len]) == ((s->clk_prevval1 - s->clk_prevval3) & lt_optimask[s->len]) ) &&
2323 			( (delta2=(s->clk_prevval - s->clk_prevval2) & lt_optimask[s->len]) == ((s->clk_prevval2 - s->clk_prevval4) & lt_optimask[s->len]) ) &&
2324 			( (delta1==delta2) || ((!delta1)&&(!delta2)) )
2325 			)
2326 			{
2327 			if(s->clk_prevtrans==ULLDescriptor(~0))
2328 				{
2329 				s->clk_prevtrans = lt->timeval;
2330 				s->clk_numtrans = 0;
2331 				}
2332 			else
2333 			if(s->clk_numtrans == 0)
2334 				{
2335 				s->clk_delta = lt->timeval - s->clk_prevtrans;
2336 				s->clk_prevtrans = lt->timeval;
2337 				s->clk_numtrans++;
2338 				}
2339 			else
2340 				{
2341 				if(s->clk_delta == (lt->timeval - s->clk_prevtrans))
2342 					{
2343 					s->clk_numtrans++;
2344 					s->clk_prevtrans = lt->timeval;
2345 					if(s->clk_numtrans > LT_CLKPACK_M)
2346 						{
2347 						s->clk_prevval4 = s->clk_prevval3;
2348 						s->clk_prevval3 = s->clk_prevval2;
2349 						s->clk_prevval2 = s->clk_prevval1;
2350 						s->clk_prevval1 = s->clk_prevval;
2351 						s->clk_prevval  = ivalue;
2352 
2353 						/* printf("Clock value '%08x' for '%s' [len=%d] at %lld (#%d)\n",
2354 							ivalue, s->name, len, lt->timeval, s->clk_numtrans); */
2355 						return(1);
2356 						}
2357 					}
2358 					else
2359 					{
2360 					if(s->clk_numtrans > LT_CLKPACK_M)
2361 						{
2362 						lt_flushclock_m(lt, s);
2363 						/* flush clock then continue below! */
2364 						}
2365 						else
2366 						{
2367 						s->clk_prevtrans=ULLDescriptor(~0);
2368 						}
2369 					}
2370 				}
2371 
2372 			}
2373 			else
2374 			{
2375 			if(s->clk_numtrans > LT_CLKPACK_M)
2376 				{
2377 				lt_flushclock_m(lt, s);
2378 				/* flush clock then continue below! */
2379 				}
2380 				else
2381 				{
2382 				s->clk_prevtrans=ULLDescriptor(~0);
2383 				}
2384 			}
2385 
2386 		s->clk_prevval4 = s->clk_prevval3;
2387 		s->clk_prevval3 = s->clk_prevval2;
2388 		s->clk_prevval2 = s->clk_prevval1;
2389 		s->clk_prevval1 = s->clk_prevval;
2390 		s->clk_prevval  = ivalue;
2391 		}
2392 	else
2393 	if(len==1) /* possible clock handling */
2394 		{
2395 		if(((s->clk_prevval == '1') && (value[0]=='0')) || ((s->clk_prevval == '0') && (value[0]=='1')))
2396 			{
2397 			if(s->clk_prevtrans==ULLDescriptor(~0))
2398 				{
2399 				s->clk_prevtrans = lt->timeval;
2400 				s->clk_numtrans = 0;
2401 				}
2402 			else
2403 			if(s->clk_numtrans == 0)
2404 				{
2405 				s->clk_delta = lt->timeval - s->clk_prevtrans;
2406 				s->clk_prevtrans = lt->timeval;
2407 				s->clk_numtrans++;
2408 				}
2409 			else
2410 				{
2411 				if(s->clk_delta == (lt->timeval - s->clk_prevtrans))
2412 					{
2413 					s->clk_numtrans++;
2414 					s->clk_prevtrans = lt->timeval;
2415 					if(s->clk_numtrans > LT_CLKPACK)
2416 						{
2417 						s->clk_prevval = value[0];
2418 
2419 						/* printf("Clock value '%c' for '%s' at %lld (#%d)\n", value[0], s->name, lt->timeval, s->clk_numtrans); */
2420 						return(1);
2421 						}
2422 					}
2423 					else
2424 					{
2425 					if(s->clk_numtrans > LT_CLKPACK)
2426 						{
2427 						lt_flushclock(lt, s);
2428 						/* flush clock then continue below! */
2429 						}
2430 						else
2431 						{
2432 						s->clk_prevtrans=ULLDescriptor(~0);
2433 						}
2434 					}
2435 				}
2436 
2437 			}
2438 			else
2439 			{
2440 			if(s->clk_numtrans > LT_CLKPACK)
2441 				{
2442 				lt_flushclock(lt, s);
2443 				/* flush clock then continue below! */
2444 				}
2445 				else
2446 				{
2447 				s->clk_prevtrans=ULLDescriptor(~0);
2448 				}
2449 			}
2450 
2451 		s->clk_prevval = value[0];
2452 		}
2453 	}
2454 
2455 	/* normal trace handling */
2456 
2457 	last_change_delta = lt->position - s->last_change - 2;
2458 
2459 	if(last_change_delta >= 256*65536)
2460 		{
2461 		numbytes = 3;
2462 		}
2463 	else
2464 	if(last_change_delta >= 65536)
2465 		{
2466 		numbytes = 2;
2467 		}
2468 	else
2469 	if(last_change_delta >= 256)
2470 		{
2471 		numbytes = 1;
2472 		}
2473 	else
2474 		{
2475 		numbytes = 0;
2476 		}
2477 
2478 	pnt = value;
2479 	prevch = *pnt;
2480 	while((ch=*(pnt++)))
2481 		{
2482 		switch(ch)
2483 			{
2484 			case '0':
2485 			case '1':	mvl|=LT_MVL_2; break;
2486 			case 'Z':
2487 			case 'z':
2488 			case 'X':
2489 			case 'x':	mvl|=LT_MVL_4; break;
2490 			default:	mvl|=LT_MVL_9; break;
2491 			}
2492 
2493 		if(prevch!=ch) prevch = 0;
2494 		}
2495 
2496 	switch(prevch)
2497 		{
2498 		case 0x00:	tagadd = 0; break;
2499 		case '0':	tagadd = 3; break;
2500 		case '1':	tagadd = 4; break;
2501 		case 'Z':
2502 		case 'z':	tagadd = 5; break;
2503 		case 'X':
2504 		case 'x':	tagadd = 6; break;
2505 		case 'H':
2506 		case 'h':	tagadd = 7; break;
2507 		case 'U':
2508 		case 'u':	tagadd = 8; break;
2509 		case 'W':
2510 		case 'w':	tagadd = 9; break;
2511 		case 'L':
2512 		case 'l':	tagadd = 0xa; break;
2513 		default:	tagadd = 0xb; break;
2514 		}
2515 
2516 	if(mvl)
2517 		{
2518 		start_position = lt->position;
2519 
2520 		if(!lt->numfacs_bytes)
2521 			{
2522 			if(tagadd)
2523 				{
2524 				tag = (numbytes<<4) + tagadd;
2525 				}
2526 				else
2527 				{
2528 				tag = (numbytes<<4) + ((mvl&LT_MVL_9)? 2 : ((mvl&LT_MVL_4)? 1 : 0));
2529 				}
2530 			lt->lt_emit_u8(lt, tag);
2531 			switch(numbytes&3)
2532 				{
2533 				case 0: lt->lt_emit_u8(lt, last_change_delta); break;
2534 				case 1: lt->lt_emit_u16(lt, last_change_delta); break;
2535 				case 2: lt->lt_emit_u24(lt, last_change_delta); break;
2536 				case 3: lt->lt_emit_u32(lt, last_change_delta); break;
2537 				}
2538 			}
2539 			else
2540 			{
2541 			switch(lt->numfacs_bytes)
2542 				{
2543 				case 1: lt->lt_emit_u8(lt, s->facnum); break;
2544 				case 2: lt->lt_emit_u16(lt, s->facnum); break;
2545 				case 3: lt->lt_emit_u24(lt, s->facnum); break;
2546 				case 4: lt->lt_emit_u32(lt, s->facnum); break;
2547 				}
2548 			if(tagadd)
2549 				{
2550 				lt->lt_emit_u8(lt, tagadd);
2551 				}
2552 				else
2553 				{
2554 				lt->lt_emit_u8(lt, (mvl&LT_MVL_9)? 2 : ((mvl&LT_MVL_4)? 1 : 0) );
2555 				}
2556 			}
2557 
2558 		s->last_change = start_position;
2559 
2560 		if(s->rows>0)
2561 			{
2562 			if(s->rows >= 256*65536)
2563 				{
2564 				numbytes = 3;
2565 				}
2566 			else
2567 			if(s->rows >= 65536)
2568 				{
2569 				numbytes = 2;
2570 				}
2571 			else
2572 			if(s->rows >= 256)
2573 				{
2574 				numbytes = 1;
2575 				}
2576 			else
2577 				{
2578 				numbytes = 0;
2579 				}
2580 
2581 			switch(numbytes&3)
2582 				{
2583 				case 0: lt->lt_emit_u8(lt, row); break;
2584 				case 1: lt->lt_emit_u16(lt, row); break;
2585 				case 2: lt->lt_emit_u24(lt, row); break;
2586 				case 3: lt->lt_emit_u32(lt, row); break;
2587 				}
2588 			}
2589 
2590 		if(!tagadd)
2591 			{
2592 			unsigned int len2 = ((s->flags)&LT_SYM_F_INTEGER) ? 32 : s->len;
2593 			if((mvl & (LT_MVL_2|LT_MVL_4|LT_MVL_9)) == LT_MVL_2)
2594 				{
2595 				unsigned int i;
2596 				int bitpos = 7;
2597 				int outval = 0;
2598 				int thisval= 0;
2599 
2600 				pnt = value;
2601 
2602 				if((lt->dictmode)&&(len2>lt->mindictwidth))
2603 					{
2604 					char *vpnt = value;
2605 					while ( (*vpnt == '0') && (*(vpnt+1)) ) vpnt++;
2606 
2607 					lt->dict = dslxt_splay (vpnt, lt->dict);
2608 					if(!dslxt_success)
2609 						{
2610 						unsigned int vlen = strlen(vpnt)+1;
2611 						char *vcopy = (char *)malloc(vlen);
2612 
2613 						strcpy(vcopy, vpnt);
2614 						lt->dict_string_mem_required += vlen;
2615 						lt->dict = dslxt_insert(vcopy, lt->dict, lt->num_dict_entries);
2616 
2617 						if(!lt->dict16_offset)
2618 							{
2619 							if(lt->num_dict_entries==256) lt->dict16_offset = lt->position;
2620 							}
2621 						else
2622 						if(!lt->dict24_offset)
2623 							{
2624 							if(lt->num_dict_entries==65536) lt->dict24_offset = lt->position;
2625 							}
2626 						else
2627 						if(!lt->dict32_offset)
2628 							{
2629 							if(lt->num_dict_entries==(256*65536)) lt->dict32_offset = lt->position;
2630 							}
2631 
2632 						lt->num_dict_entries++;
2633 						}
2634 
2635 					if(lt->dict24_offset)
2636 						{
2637 						if(lt->dict32_offset)
2638 							{
2639 							lt->lt_emit_u32(lt, lt->dict->val);
2640 							}
2641 							else
2642 							{
2643 							lt->lt_emit_u24(lt, lt->dict->val);
2644 							}
2645 						}
2646 					else
2647 						{
2648 						if(lt->dict16_offset)
2649 							{
2650 							lt->lt_emit_u16(lt, lt->dict->val);
2651 							}
2652 							else
2653 							{
2654 							lt->lt_emit_u8(lt, lt->dict->val);
2655 							}
2656 						}
2657 					}
2658 				else
2659 				for(i=0;i<len2;i++)
2660 					{
2661 					if(*pnt)
2662 						{
2663 						thisval = (*pnt=='1');
2664 						pnt++;
2665 						}
2666 					outval |= (thisval<<bitpos);
2667 					bitpos--;
2668 					if((bitpos==-1)||(i==len2-1))
2669 						{
2670 						lt->lt_emit_u8(lt, outval);
2671 						outval = 0;
2672 						bitpos = 7;
2673 						}
2674 					}
2675 				}
2676 			else
2677 			if((mvl & (LT_MVL_4|LT_MVL_9)) == LT_MVL_4)
2678 				{
2679 				unsigned int i;
2680 				int bitpos = 6;
2681 				int outval = 0;
2682 				int thisval= 0;
2683 
2684 				pnt = value;
2685 
2686 				for(i=0;i<len2;i++)
2687 					{
2688 					if(*pnt)
2689 						{
2690 						switch(*pnt)
2691 							{
2692 							case '0':	thisval = 0; break;
2693 							case '1':	thisval = 1; break;
2694 							case 'X':
2695 							case 'x':	thisval = 3; break;
2696 							default:	thisval = 2; break;
2697 							}
2698 						pnt++;
2699 						}
2700 					outval |= (thisval<<bitpos);
2701 					bitpos-=2;
2702 					if((bitpos==-2)||(i==len2-1))
2703 						{
2704 						lt->lt_emit_u8(lt, outval);
2705 						outval = 0;
2706 						bitpos = 6;
2707 						}
2708 					}
2709 				}
2710 			else
2711 			/* if(mvl & LT_MVL_9) */
2712 				{
2713 				unsigned int i;
2714 				int bitpos = 4;
2715 				int outval = 0;
2716 				int thisval= 0;
2717 
2718 				pnt = value;
2719 
2720 				for(i=0;i<len2;i++)
2721 					{
2722 					if(*pnt)
2723 						{
2724 						switch(*pnt)
2725 							{
2726 							case '0':	thisval = 0; break;
2727 							case '1':	thisval = 1; break;
2728 							case 'Z':
2729 							case 'z':	thisval = 2; break;
2730 							case 'X':
2731 							case 'x':	thisval = 3; break;
2732 							case 'H':
2733 							case 'h':	thisval = 4; break;
2734 							case 'U':
2735 							case 'u':	thisval = 5; break;
2736 							case 'W':
2737 							case 'w':	thisval = 6; break;
2738 							case 'L':
2739 							case 'l':	thisval = 7; break;
2740 							default:	thisval = 8; break;
2741 							}
2742 						pnt++;
2743 						}
2744 					outval |= (thisval<<bitpos);
2745 					bitpos-=4;
2746 					if((bitpos==-4)||(i==len2-1))
2747 						{
2748 						lt->lt_emit_u8(lt, outval);
2749 						outval = 0;
2750 						bitpos = 4;
2751 						}
2752 					}
2753 				}
2754 			}
2755 
2756 		rc=1;
2757 		}
2758 
2759 	if(lt->timebuff)
2760 		{
2761 		lt->timechangecount++;
2762 		if(lt->timecurr)
2763 			{
2764 			lt->timecurr->next = lt->timebuff;
2765 			lt->timecurr = lt->timebuff;
2766 			}
2767 			else
2768 			{
2769 			lt->timehead = lt->timecurr = lt->timebuff;
2770 			}
2771 
2772 		lt->timebuff=NULL;
2773 		}
2774 	}
2775 
2776 return(rc);
2777 }
2778 
2779 
2780 /*
2781  * blackout functions
2782  */
lt_set_dumpoff(struct lt_trace * lt)2783 void lt_set_dumpoff(struct lt_trace *lt)
2784 {
2785 if((lt)&&(!lt->dumpoff_active))
2786 	{
2787 	struct lt_timetrail *ltt = calloc(1, sizeof(struct lt_timetrail));
2788 
2789 	ltt->timeval = lt->timeval;
2790 	if(lt->dumpoffhead)
2791 		{
2792 		lt->dumpoffcurr->next = ltt;
2793 		lt->dumpoffcurr = ltt;
2794 		}
2795 		else
2796 		{
2797 		lt->dumpoffhead = lt->dumpoffcurr = ltt;
2798 		}
2799 
2800 	lt->dumpoff_active = 1;
2801 	lt->dumpoffcount++;
2802 	}
2803 }
2804 
lt_set_dumpon(struct lt_trace * lt)2805 void lt_set_dumpon(struct lt_trace *lt)
2806 {
2807 if((lt)&&(lt->dumpoff_active))
2808 	{
2809 	struct lt_timetrail *ltt = calloc(1, sizeof(struct lt_timetrail));
2810 
2811 	ltt->timeval = lt->timeval;
2812 
2813 	lt->dumpoffcurr->next = ltt;
2814 	lt->dumpoffcurr = ltt;
2815 
2816 	lt->dumpoff_active = 0;
2817 	}
2818 }
2819 
lt_set_timezero(struct lt_trace * lt,lxtotime_t timeval)2820 void lt_set_timezero(struct lt_trace *lt, lxtotime_t timeval)
2821 {
2822 if(lt)
2823 	{
2824 	lt->timezero = timeval;
2825 	}
2826 }
2827 
2828