1 /******************************************************************************
2  * DESCRIPTION: Dinotrace source: trace file reading
3  *
4  * This file is part of Dinotrace.
5  *
6  * Author: Wilson Snyder <wsnyder@wsnyder.org>
7  *
8  * Code available from: http://www.veripool.org/dinotrace
9  *
10  ******************************************************************************
11  *
12  * Some of the code in this file was originally developed for Digital
13  * Semiconductor, a division of Digital Equipment Corporation.  They
14  * gratefuly have agreed to share it, and thus the base version has been
15  * released to the public with the following provisions:
16  *
17  *
18  * This software is provided 'AS IS'.
19  *
20  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THE INFORMATION
21  * (INCLUDING ANY SOFTWARE) PROVIDED, INCLUDING ALL IMPLIED WARRANTIES OF
22  * MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE, AND
23  * NON-INFRINGEMENT. DIGITAL NEITHER WARRANTS NOR REPRESENTS THAT THE USE
24  * OF ANY SOURCE, OR ANY DERIVATIVE WORK THEREOF, WILL BE UNINTERRUPTED OR
25  * ERROR FREE.  In no event shall DIGITAL be liable for any damages
26  * whatsoever, and in particular DIGITAL shall not be liable for special,
27  * indirect, consequential, or incidental damages, or damages for lost
28  * profits, loss of revenue, or loss of use, arising out of or related to
29  * any use of this software or the information contained in it, whether
30  * such damages arise in contract, tort, negligence, under statute, in
31  * equity, at law or otherwise. This Software is made available solely for
32  * use by end users for information and non-commercial or personal use
33  * only.  Any reproduction for sale of this Software is expressly
34  * prohibited. Any rights not expressly granted herein are reserved.
35  *
36  ******************************************************************************
37  *
38  * Changes made over the basic version are covered by the GNU public licence.
39  *
40  * Dinotrace is free software; you can redistribute it and/or modify
41  * it under the terms of the GNU General Public License as published by
42  * the Free Software Foundation; either version 3, or (at your option)
43  * any later version.
44  *
45  * Dinotrace is distributed in the hope that it will be useful,
46  * but WITHOUT ANY WARRANTY; without even the implied warranty of
47  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48  * GNU General Public License for more details.
49  *
50  * You should have received a copy of the GNU General Public License
51  * along with Dinotrace; see the file COPYING.  If not, write to
52  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
53  * Boston, MA 02111-1307, USA.
54  *
55  *****************************************************************************/
56 
57 #include "dinotrace.h"
58 
59 #include "assert.h"
60 #include <Xm/Text.h>
61 #include <Xm/MessageB.h>
62 #include <Xm/SelectioB.h>
63 #include <Xm/FileSB.h>
64 #include <Xm/Form.h>
65 #include <Xm/PushB.h>
66 #include <Xm/PushBG.h>
67 #include <Xm/ToggleB.h>
68 #include <Xm/RowColumn.h>
69 
70 #include "functions.h"
71 
72 #if HAVE_DINODOC_H
73 #include "dinodoc.h"
74 #else
75 char dinodoc[] = "Unavailable";
76 #endif
77 
78 /****************************** UTILITIES ******************************/
79 
free_data(Trace_t * trace)80 void free_data (
81     /* Free trace information, also used when deleting preserved structure */
82     Trace_t	*trace)
83 {
84     Trace_t	*trace_ptr;
85 
86     if (DTPRINT_ENTRY) printf ("In free_data - trace=%p\n",trace);
87 
88     if (!trace || !trace->loaded) return;
89     trace->loaded = 0;
90     trace->numsigstart = 0;
91 
92     /* free any added signals in other traces from this trace */
93     for (trace_ptr = global->deleted_trace_head; trace_ptr; trace_ptr = trace_ptr->next_trace) {
94 	sig_free (trace, trace_ptr->firstsig, TRUE, TRUE);
95     }
96     /* free signal data and each signal structure */
97     sig_free (trace, trace->firstsig, FALSE, TRUE);
98     trace->firstsig = NULL;
99     trace->lastsig = NULL;
100     trace->dispsig = NULL;
101     trace->numsig = 0;
102 }
103 
trace_read_cb(Widget w,Trace_t * trace)104 void trace_read_cb (
105     Widget		w,
106     Trace_t		*trace)
107 {
108     int		i;
109 
110     if (DTPRINT_ENTRY) printf ("In trace_read_cb - trace=%p\n",trace);
111 
112     /* Clear the file format */
113     trace->dfile.fileformat = FF_AUTO;
114 
115     if (!trace->fileselect.dialog) {
116 	XtSetArg (arglist[0], XmNdefaultPosition, TRUE);
117 	XtSetArg (arglist[1], XmNdialogTitle, XmStringCreateSimple ("Open Trace File") );
118 
119 	trace->fileselect.dialog = XmCreateFileSelectionDialog ( trace->main, "file", arglist, 2);
120 	DAddCallback (trace->fileselect.dialog, XmNokCallback, fil_ok_cb, trace);
121 	DAddCallback (trace->fileselect.dialog, XmNcancelCallback, (XtCallbackProc)unmanage_cb, trace->fileselect.dialog);
122 	XtUnmanageChild ( XmFileSelectionBoxGetChild (trace->fileselect.dialog, XmDIALOG_HELP_BUTTON));
123 
124 	trace->fileselect.work_area = XmCreateWorkArea (trace->fileselect.dialog, "wa", arglist, 0);
125 
126 	/* Create FILE FORMAT */
127 	trace->fileselect.format_menu = XmCreatePulldownMenu (trace->fileselect.work_area,"fmtrad",arglist,0);
128 
129 	for (i=0; i<FF_NUMFORMATS; i++) {
130 	    if (filetypes[i].selection) {
131 		XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple (filetypes[i].name) );
132 		trace->fileselect.format_item[i] =
133 		    XmCreatePushButtonGadget (trace->fileselect.format_menu,"pdbutton",arglist,1);
134 		DManageChild (trace->fileselect.format_item[i], trace, MC_NOKEYS);
135 		DAddCallback (trace->fileselect.format_item[i], XmNactivateCallback, fil_format_option_cb, trace);
136 	    }
137 	}
138 
139 	XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple ("File Format"));
140 	XtSetArg (arglist[1], XmNsubMenuId, trace->fileselect.format_menu);
141 	trace->fileselect.format_option = XmCreateOptionMenu (trace->fileselect.work_area,"format",arglist,2);
142 	DManageChild (trace->fileselect.format_option, trace, MC_NOKEYS);
143 
144 	/* Create save_ordering button */
145 	XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple ("Preserve Signal Ordering"));
146 	XtSetArg (arglist[1], XmNshadowThickness, 1);
147 	trace->fileselect.save_ordering = XmCreateToggleButton (trace->fileselect.work_area,"save_ordering",arglist,2);
148 	DManageChild (trace->fileselect.save_ordering, trace, MC_NOKEYS);
149 
150 	DManageChild (trace->fileselect.work_area, trace, MC_NOKEYS);
151 
152 	XSync (global->display,0);
153     }
154 
155     /* Ordering */
156     XtSetArg (arglist[0], XmNset, global->save_ordering ? 1:0);
157     XtSetValues (trace->fileselect.save_ordering,arglist,1);
158 
159     /* File format */
160     if (filetypes[file_format].selection) {
161 	XtSetArg (arglist[0], XmNmenuHistory, trace->fileselect.format_item[file_format]);
162 	XtSetValues (trace->fileselect.format_option, arglist, 1);
163     }
164 
165     /* Set directory */
166     XtSetArg (arglist[0], XmNdirectory, XmStringCreateSimple (global->directory) );
167     XtSetValues (trace->fileselect.dialog,arglist,1);
168 
169     fil_select_set_pattern (trace, trace->fileselect.dialog, filetypes[file_format].mask);
170 
171     DManageChild (trace->fileselect.dialog, trace, MC_NOKEYS);
172 
173     XSync (global->display,0);
174 }
175 
trace_reread_all()176 void trace_reread_all ()
177 {
178     Trace_t*		trace;
179     for (trace = global->trace_head; trace; trace = trace->next_trace) {
180 	if (trace->loaded) {
181 	    trace_reread(trace);
182 	}
183     }
184 }
185 
trace_reread(Trace_t * trace)186 void trace_reread (
187     Trace_t		*trace)
188 {
189     char *semi;
190     int		read_fd;
191     struct stat		newstat;	/* New status on the reread file*/
192 
193     if (!trace->loaded)
194 	trace_read_cb (NULL, trace);
195     else {
196 	/* Drop ;xxx */
197 	if ((semi = strchr (trace->dfile.filename,';')))
198 	    *semi = '\0';
199 
200 	if (DTPRINT_ENTRY) printf ("In trace_reread_cb - rereading file=%s\n",trace->dfile.filename);
201 
202 	/* check the date first */
203 	read_fd = open (trace->dfile.filename, O_RDONLY, 0);
204 	if (read_fd>=1) {
205 	    /* Opened ok */
206 	    fstat (read_fd, &newstat);
207 	    close (read_fd);
208 	    if ((newstat.st_mtime == trace->dfile.filestat.st_mtime)
209 		&& (newstat.st_ctime == trace->dfile.filestat.st_ctime)) {
210 		if (DTPRINT_FILE) printf ("  file has not changed.\n");
211 		if (DTPRINT_FILE) printf ("  file has not changed, but rereading anyways.\n");
212 		else return;
213 	    }
214 	}
215 
216 	/* read the file */
217 	fil_read (trace);
218     }
219 }
220 
fil_read(Trace_t * trace)221 void fil_read (
222     Trace_t	*trace)
223 {
224     int		read_fd;
225     FILE	*read_fp;	/* Routines are responsible for assigning this! */
226     char	*pchar;
227     char 	pipecmd[MAXFNAMELEN+20];
228     pipecmd[0]='\0';	/* MIPS: no automatic aggregate initialization */
229     read_fp = NULL;	/* MIPS: no automatic aggregate initialization */
230 
231     if (DTPRINT_ENTRY) printf ("In fil_read trace=%p filename=%s\n",trace,trace->dfile.filename);
232 
233     /* Update directory name */
234     strcpy (global->directory, trace->dfile.filename);
235     file_directory (global->directory);
236 
237     /* Clear the data structures & the screen */
238     XClearWindow (global->display, trace->wind);
239     set_cursor (DC_BUSY);
240     XSync (global->display,0);
241 
242     /* free memory associated with the data */
243     sig_cross_preserve(trace);
244     free_data (trace);
245 
246     /* get applicable config files */
247     config_read_defaults (trace, TRUE);
248 
249     /* Compute the file format */
250     if (trace->dfile.fileformat == FF_AUTO) {
251 	trace->dfile.fileformat =	file_format;
252     }
253 
254     /* Normalize format */
255     switch (trace->dfile.fileformat) {
256     case	FF_AUTO:
257     case	FF_DECSIM:
258     case	FF_DECSIM_BIN:
259 #ifdef VMS
260 	trace->dfile.fileformat =	FF_DECSIM_BIN;
261 #else
262 	/* Binary relys on varible RMS records - Ultrix has no such thing */
263 	trace->dfile.fileformat =	FF_DECSIM_ASCII;
264 #endif
265 	break;
266 	/* No default */
267     }
268 
269     /* Open file and copy descriptor information */
270     read_fd = open (trace->dfile.filename, O_RDONLY, 0);
271     if (read_fd>0) {
272 	fstat (read_fd, &(trace->dfile.filestat));
273 #ifndef VMS
274 	if (! S_ISREG(trace->dfile.filestat.st_mode)) {
275 	    /* Not regular file */
276 	    close (read_fd);
277 	    read_fd = -1;
278 	}
279 #endif
280     }
281     if (read_fd<1) {
282 	/* Similar code below! */
283 	sprintf (message,"Can't open file %s", trace->dfile.filename);
284 	dino_error_ack (trace, message);
285 
286 	/* Clear cursor and return*/
287 	sig_cross_restore (trace);
288 	change_title (trace);
289 	set_cursor (DC_NORMAL);
290 	return;
291     }
292 
293 #ifndef VMS
294     /* If compressed, close the file and open as uncompressed */
295     pipecmd[0]='\0';
296     if ((pchar=strrchr(trace->dfile.filename,'.')) != NULL ) {
297 	if (!strcmp (pchar, ".Z")) sprintf (pipecmd, "uncompress -c %s", trace->dfile.filename);
298 	if (!strcmp (pchar, ".gz")) sprintf (pipecmd, "gunzip -c %s", trace->dfile.filename);
299     }
300 
301     if (trace->dfile.fileformat == FF_VERILOG_VPD) {
302 	if (pipecmd[0]) {
303 	    /* Because vpd2vcd fseeks, it won't take a pipe as input, and we... */
304 	    sprintf (message,"Can't unzip/uncompress VPD traces.");
305 	    dino_error_ack (trace, message);
306 	    return;
307 	}
308 	sprintf (pipecmd, "vpd2vcd %s 2>/dev/null", trace->dfile.filename);
309     }
310 
311     if (pipecmd[0]) {
312 
313 	if (DTPRINT_FILE) printf ("Piping: %s\n", pipecmd);
314 
315 	/* Decsim must be ASCII because of record format */
316 	if (trace->dfile.fileformat == FF_DECSIM_BIN) trace->dfile.fileformat = FF_DECSIM_ASCII;
317 
318 	/* Close compressed file and open uncompressed file */
319 	close (read_fd);
320 
321 	read_fp = popen (pipecmd, "r");
322 	read_fd = fileno (read_fp);
323 	if (!read_fp) {
324 	    /* Similar above! */
325 	    sprintf (message,"Can't create pipe with command '%s'", pipecmd);
326 	    dino_error_ack (trace, message);
327 
328 	    /* Clear cursor and return */
329 	    sig_cross_restore (trace);
330 	    change_title (trace);
331 	    set_cursor (DC_NORMAL);
332 	    return;
333 	}
334     }
335 #endif
336 
337     /*
338      ** Read in the trace file using the format selected by the user
339      */
340     switch (trace->dfile.fileformat) {
341       case	FF_DECSIM_BIN:
342 #ifdef VMS
343 	decsim_read_binary (trace, read_fd);
344 #endif /* VMS */
345 	break;
346       case	FF_TEMPEST:
347 	tempest_read (trace, read_fd);
348 	break;
349       case	FF_VERILOG:
350       case	FF_VERILOG_VPD:
351 	verilog_read (trace, read_fd);
352 	break;
353       case	FF_DECSIM_ASCII:
354 	ascii_read (trace, read_fd, read_fp);
355 	break;
356       default:
357 	fprintf (stderr, "Unknown file format!!\n");
358     }
359 
360     /* Close the file */
361     if (pipecmd[0] == '\0') {
362 	close (read_fd);
363     }
364 #ifndef VMS
365     else {
366 	fflush (read_fp);
367 	pclose (read_fp);
368     }
369 #endif
370 
371     /* Now add EOT to each signal and reset the cptr */
372     fil_trace_end (trace);
373 
374     /* Change the name on title bar to filename */
375     change_title (trace);
376 
377     /*
378      ** Clear the window and draw the screen with the new file
379      */
380     set_cursor (DC_NORMAL);
381     if (global->res_default) win_full_res (trace);
382     new_time (trace);		/* Realignes start and displays */
383     vscroll_new (trace,0);	/* Realign time */
384     if (DTPRINT_ENTRY) printf ("fil_read done!\n");
385 }
386 
fil_select_set_pattern(Trace_t * trace,Widget dialog,char * pattern)387 void  fil_select_set_pattern (
388     Trace_t	*trace,
389     Widget	dialog,
390     char	*pattern)
391     /* Set the file requester pattern information (called in 2 places) */
392 {
393     char mask[MAXFNAMELEN], *dirname;
394     XmString	xs_dirname;
395 
396     /* Grab directory information */
397     XtSetArg (arglist[0], XmNdirectory, &xs_dirname);
398     XtGetValues (dialog, arglist, 1);
399     dirname = extract_first_xms_segment (xs_dirname);
400 
401     /* Pattern information */
402     strcpy (mask, dirname);
403     strcat (mask, pattern);
404     XtSetArg (arglist[0], XmNdirMask, XmStringCreateSimple (mask) );
405     XtSetArg (arglist[1], XmNpattern, XmStringCreateSimple (pattern) );
406     XtSetValues (dialog,arglist,2);
407 }
408 
fil_format_option_cb(Widget w,Trace_t * trace,XmSelectionBoxCallbackStruct * cb)409 void    fil_format_option_cb (
410     Widget	w,
411     Trace_t	*trace,
412     XmSelectionBoxCallbackStruct *cb)
413 {
414     int 	i;
415     if (DTPRINT_ENTRY) printf ("In fil_format_option_cb trace=%p\n",trace);
416 
417     for (i=0; i<FF_NUMFORMATS; i++) {
418 	if (w == trace->fileselect.format_item[i]) {
419 	    file_format = i;	/* Change global verion */
420 	    trace->dfile.fileformat = i;	/* Specifically make this file use this format */
421 	    fil_select_set_pattern (trace, trace->fileselect.dialog, filetypes[file_format].mask);
422 	}
423     }
424 }
425 
fil_ok_cb(Widget w,Trace_t * trace,XmFileSelectionBoxCallbackStruct * cb)426 void fil_ok_cb (
427     Widget	w,
428     Trace_t	*trace,
429     XmFileSelectionBoxCallbackStruct *cb)
430 {
431     char	*tmp;
432 
433     if (DTPRINT_ENTRY) printf ("In fil_ok_cb trace=%p\n",trace);
434 
435     /*
436      ** Unmanage the file select widget here and wait for sync so
437      ** the window goes away before the read process begins in case
438      ** the idle is very big.
439      */
440     XtUnmanageChild (trace->fileselect.dialog);
441     XSync (global->display,0);
442 
443     tmp = extract_first_xms_segment (cb->value);
444     if (DTPRINT_FILE) printf ("filename=%s\n",tmp);
445 
446     global->save_ordering = XmToggleButtonGetState (trace->fileselect.save_ordering);
447 
448     strcpy (trace->dfile.filename, tmp);
449 
450     DFree (tmp);
451 
452     if (DTPRINT_FILE) printf ("In fil_ok_cb Filename=%s\n",trace->dfile.filename);
453     fil_read (trace);
454 }
455 
456 
help_cb(Widget w)457 void help_cb (
458     Widget	w)
459 {
460     Trace_t *trace = widget_to_trace(w);
461     if (DTPRINT_ENTRY) printf ("in help_cb\n");
462     dino_information_ack (trace, help_message ());
463 }
464 
help_trace_cb(Widget w)465 void help_trace_cb (
466     Widget	w)
467 {
468     Trace_t *trace = widget_to_trace(w);
469     static char msg[2000];
470     static char msg2[1000];
471 
472     if (DTPRINT_ENTRY) printf ("in help_trace_cb\n");
473 
474     if (!trace->loaded) {
475 	sprintf (msg, "No trace is loaded.\n");
476     }
477     else {
478 	sprintf (msg, "%s\n\n", trace->dfile.filename);
479 
480 	sprintf (msg2, "File Format: %s\n", filetypes[trace->dfile.fileformat].name);
481 	strcat (msg, msg2);
482 
483 	sprintf (msg2, "File Modified Date: %s\n", date_string (trace->dfile.filestat.st_ctime));
484 	strcat (msg, msg2);
485 
486 	sprintf (msg2, "File Creation Date: %s\n", date_string (trace->dfile.filestat.st_mtime));
487 	strcat (msg, msg2);
488 
489 	sprintf (msg2, "\nTimes stored to nearest: %s\n", time_units_to_string (global->time_precision, TRUE));
490 	strcat (msg, msg2);
491     }
492 
493     dino_information_ack (trace, msg);
494 }
495 
496 
help_doc_cb(Widget w)497 void help_doc_cb (
498     Widget	w)
499 {
500     Trace_t *trace = widget_to_trace(w);
501 
502     if (DTPRINT_ENTRY) printf ("in help_doc_cb\n");
503 
504     /* May be called before the window was opened, if so ignore the help_doc */
505     if (!trace->work) return;
506 
507     /* create the widget if it hasn't already been */
508     if (!trace->help_doc) {
509 	XtSetArg (arglist[0], XmNdefaultPosition, TRUE);
510 	XtSetArg (arglist[1], XmNdialogTitle, XmStringCreateSimple ("Dinotrace Documentation") );
511 	trace->help_doc = XmCreateInformationDialog (trace->work, "info", arglist, 2);
512 	DAddCallback (trace->help_doc, XmNokCallback, unmanage_cb, trace->help_doc);
513 	XtUnmanageChild ( XmMessageBoxGetChild (trace->help_doc, XmDIALOG_CANCEL_BUTTON));
514 	XtUnmanageChild ( XmMessageBoxGetChild (trace->help_doc, XmDIALOG_HELP_BUTTON));
515 
516 	/* create scrolled text widget */
517 	XtSetArg (arglist[0], XmNrows, 40);
518 	XtSetArg (arglist[1], XmNcolumns, 80);
519 	XtSetArg (arglist[2], XmNeditable, FALSE);
520 	XtSetArg (arglist[3], XmNvalue, dinodoc);
521 	XtSetArg (arglist[4], XmNscrollVertical, TRUE);
522 	XtSetArg (arglist[5], XmNeditMode, XmMULTI_LINE_EDIT);
523 	XtSetArg (arglist[6], XmNscrollHorizontal, FALSE);
524 	trace->help_doc_text = XmCreateScrolledText (trace->help_doc,"textn",arglist,7);
525 
526 	DManageChild (trace->help_doc_text, trace, MC_NOKEYS);
527     }
528 
529     /* manage the widget */
530     DManageChild (trace->help_doc, trace, MC_NOKEYS);
531 }
532 
533 #if !defined (fil_add_cptr)
534 #ifdef VMS
535 #pragma inline (fil_add_cptr)
536 #endif
537 /* WARNING, INLINED CODE IN FUNCTIONS.H */
fil_add_cptr(Signal_t * sig_ptr,Value_t * value_ptr,Boolean_t nocheck)538 void	fil_add_cptr (
539     Signal_t	*sig_ptr,
540     Value_t	*value_ptr,
541     Boolean_t	nocheck)		/* compare against previous data */
542 {
543     ulong_t	diff;
544     Value_t	*cptr = sig_ptr->cptr;
545 
546     /* Important! During the adding cptr points to the __last__ value added, not the next! */
547 
548     /*
549     if (DTPRINT_FILE) printf ("Checking st %d v %d tm %d with st %d v %d time %d\n",
550 	    value_ptr->siglw.stbits.state, value_ptr->number[0],
551 	    CPTR_TIME(value_ptr),
552 	    cptr->siglw.stbits.state,      cptr->number[0],
553 	    CPTR_TIME(cptr)
554 	    );
555     if (DTPRINT_FILE) printf ("val: %08x %08x %08x %08x %08x %08x    ",
556 	    value_ptr->siglw.number, value_ptr->time,
557 	    value_ptr->number[0],value_ptr->number[1],
558 	    value_ptr->number[2],value_ptr->number[3]);
559     */
560 
561     /* Comparing all 4 LW's works because we keep the unused LWs zeroed */
562     if ( nocheck
563 	|| ( cptr->siglw.stbits.state != value_ptr->siglw.stbits.state )
564 	|| ( cptr->number[0] != value_ptr->number[0] )
565 	|| ( cptr->number[1] != value_ptr->number[1] )
566 	|| ( cptr->number[2] != value_ptr->number[2] )
567 	|| ( cptr->number[3] != value_ptr->number[3] )
568 	|| ( cptr->number[4] != value_ptr->number[4] )
569 	|| ( cptr->number[5] != value_ptr->number[5] )
570 	|| ( cptr->number[6] != value_ptr->number[6] )
571 	|| ( cptr->number[7] != value_ptr->number[7] ) ) {
572 
573 	diff = (uint_t*)sig_ptr->cptr - (uint_t*)sig_ptr->bptr;
574 	if (diff > sig_ptr->blocks ) {
575 	    /* if (DTPRINT_FILE) printf ("Realloc\n"); */
576 	    sig_ptr->blocks += BLK_SIZE;
577 	    sig_ptr->bptr = (Value_t *)XtRealloc
578 		((char*)sig_ptr->bptr,
579 		 (sig_ptr->blocks*sizeof(uint_t)) + (sizeof(Value_t)*2 + 2));
580 	    sig_ptr->cptr = (Value_t *)((uint_t*)sig_ptr->bptr + diff);
581 	}
582 
583 	/* Update size of previous */
584 	/* Note that if at the beginning of a trace, the loaded value may */
585 	/* be from uninitialized data, in that case we don't care about the size */
586 	value_ptr->siglw.stbits.size_prev = sig_ptr->cptr->siglw.stbits.size;
587 	value_ptr->siglw.stbits.size = STATE_SIZE(value_ptr->siglw.stbits.state);
588 	if (sig_ptr->cptr->siglw.number || sig_ptr->cptr!=sig_ptr->bptr) {
589 	    /* Not empty cptr list... have loaded something */
590 	    sig_ptr->cptr = CPTR_NEXT(sig_ptr->cptr);
591 	}
592 
593 	/* Load new datum */
594 	val_copy (sig_ptr->cptr, value_ptr);
595 	/*if (DTPRINT_FILE) print_sig_info(sig_ptr);*/
596     }
597 
598 }
599 #endif
600 
fil_make_busses(Trace_t * trace,Boolean_t not_tempest)601 void fil_make_busses (
602     /* Take the list of signals and make it into a list of busses */
603     /* Also do the common stuff required for each signal. */
604     Trace_t	*trace,
605     Boolean_t	not_tempest)	/* Use the name of the bus to find the bit vectors */
606 {
607     Signal_t	*sig_ptr;	/* ptr to current signal (lower bit number) */
608     int		pos;
609     char	postbusstuff[MAXSIGLEN] = "";
610 
611     if (DTPRINT_ENTRY) printf ("In fil_make_busses\n");
612     if (DTPRINT_BUSSES) sig_print_names (trace);
613 
614     /* Calculate numsig */
615     /* and allocate Signal's cptr, bptr, blocks, inc, type */
616     trace->numsig = 0;
617     for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_ptr->forward) {
618 	/* Stash the characters after the bus name */
619 	if (sig_ptr->signame_buspos) strcpy (postbusstuff, sig_ptr->signame_buspos);
620 
621 	/* Change the name to include the vector subscripts */
622 	if (sig_ptr->msb_index >= 0) {
623 	    /* Add new vector info */
624 	    if (sig_ptr->bits >= 2) {
625 		sprintf (sig_ptr->signame + strlen (sig_ptr->signame), "[%d:%d]",
626 			 sig_ptr->msb_index, sig_ptr->lsb_index);
627 	    }
628 	    else {
629 		sprintf (sig_ptr->signame + strlen (sig_ptr->signame), "[%d]",
630 			 sig_ptr->msb_index);
631 	    }
632 	}
633 
634 	/* Restore the characters after the bus name */
635 	if (sig_ptr->signame_buspos) {
636             sig_ptr->signame = XtRealloc(sig_ptr->signame,
637 					 strlen (sig_ptr->signame) + strlen (postbusstuff) + 1);
638             strcat (sig_ptr->signame, postbusstuff);
639         }
640 
641 	/* Calc numsig, last_sig_ptr */
642 	(trace->numsig) ++;
643 
644 	/* Create the bussed name & type */
645 	if (sig_ptr->bits < 2) {
646 	    sig_ptr->type = 0;
647 	}
648 	else if (sig_ptr->bits < 33) {
649 	    sig_ptr->type = STATE_B32;
650 	}
651 	else if (sig_ptr->bits < 129) {
652 	    sig_ptr->type = STATE_B128;
653 	}
654 
655 	/* Compute value_mask.  This mask ANDed with the value will clear any bits that
656 	   are not represented in this vector.  For example a 12 bit vector will only have the lower
657 	   twelve bits set, all others will be clear */
658 
659 	sig_ptr->value_mask[3] = sig_ptr->value_mask[2] = sig_ptr->value_mask[1] = sig_ptr->value_mask[0] = 0;
660 
661 	if (sig_ptr->bits > 127) sig_ptr->value_mask[3] = 0xFFFFFFFF;
662 	else if (sig_ptr->bits > 96 ) sig_ptr->value_mask[3] = (0x7FFFFFFF >> (127-sig_ptr->bits));
663 	else if (sig_ptr->bits > 95 ) sig_ptr->value_mask[2] = 0xFFFFFFFF;
664 	else if (sig_ptr->bits > 64 ) sig_ptr->value_mask[2] = (0x7FFFFFFF >> (95-sig_ptr->bits));
665 	else if (sig_ptr->bits > 63 ) sig_ptr->value_mask[1] = 0xFFFFFFFF;
666 	else if (sig_ptr->bits > 32 ) sig_ptr->value_mask[1] = (0x7FFFFFFF >> (63-sig_ptr->bits));
667 	else if (sig_ptr->bits > 31 ) sig_ptr->value_mask[0] = 0xFFFFFFFF;
668 	else sig_ptr->value_mask[0] = (0x7FFFFFFF >> (31-sig_ptr->bits));
669 
670 	if (sig_ptr->value_mask[3]) sig_ptr->value_mask[2] = 0xFFFFFFFF;
671 	if (sig_ptr->value_mask[2]) sig_ptr->value_mask[1] = 0xFFFFFFFF;
672 	if (sig_ptr->value_mask[1]) sig_ptr->value_mask[0] = 0xFFFFFFFF;
673 
674 	/* Compute the position mask.  This is used to convert a LW from the file into a LW for the
675 	   value.  A condition is to prevent sign extension.  */
676 	pos = sig_ptr->file_pos & 0x1F;		/* Must be position of LSB */
677 	if (pos!=0) sig_ptr->pos_mask = (0x7FFFFFFF >> (pos-1));
678 	else	     sig_ptr->pos_mask = 0xFFFFFFFF;
679 
680 	/* Compute the ending position of this data (DECSIM_Binary) */
681 	sig_ptr->file_end_pos = sig_ptr->file_pos
682 	    + ((sig_ptr->file_type.flag.four_state) ? 2:1) * (sig_ptr->bits-1);
683 
684 	/* allocate the data storage memory */
685 	if (!sig_ptr->copyof) {
686 	    sig_ptr->blocks = BLK_SIZE;
687 	    sig_ptr->bptr = (Value_t *)XtMalloc ((sig_ptr->blocks*sizeof(uint_t))
688 						 + (sizeof(Value_t)*2 + 2));
689 	    val_zero (sig_ptr->bptr);	/* So we know is empty */
690 	} else {
691 	    sig_ptr->bptr = NULL;
692 	}
693     }
694 
695     /* Must be separate loop, as bptr may change in a copyof's parent */
696     for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_ptr->forward) {
697 	sig_ptr->cptr = sig_ptr->bptr;
698     }
699 
700     if (DTPRINT_BUSSES) sig_print_names (trace);
701 }
702 
703 
fil_mark_cptr_end(Trace_t * trace)704 static void fil_mark_cptr_end (
705     Trace_t	*trace)
706 {
707     Signal_t	*sig_ptr, *sig_next_ptr;
708     Value_t	value;
709     Boolean_t	msg=FALSE;
710 
711     /* loop thru each signal */
712     for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_next_ptr) {
713 	sig_next_ptr = sig_ptr->forward;
714 
715 	if (!sig_ptr->copyof) {
716 	    /* Must be a cptr which has the same time as the last time on the screen */
717 	    /* If none exists, create it */
718 	    val_zero(&value);
719 
720 	    if (sig_ptr->cptr && (sig_ptr->cptr->siglw.number || sig_ptr->cptr!=sig_ptr->bptr)) {
721 		Value_t	*cptr = sig_ptr->cptr;
722 		if (CPTR_TIME(cptr) != trace->end_time) {
723 		    val_copy (&value, sig_ptr->cptr);
724 		    value.time = trace->end_time;
725 		    fil_add_cptr (sig_ptr, &value, TRUE);
726 		}
727 	    }
728 	    else {
729 		if (DTDEBUG && !msg) {
730 		    printf ("%%W, No data for signal %s\n\tAdditional messages suppressed\n", sig_ptr->signame);
731 		    msg = TRUE;
732 		}
733 		/* Don't delete, may have copies pointing to it */
734 		/* sig_free (trace, sig_ptr, FALSE, FALSE); sig_ptr=NULL; */
735 		/* continue; */
736 	    }
737 
738 	    /* Mark end of time */
739 	    value.time = EOT;
740 	    fil_add_cptr (sig_ptr, &value, TRUE);
741 	}
742     }
743 
744     /* Must be separate loop, as bptr may change in a copyof's parent */
745     for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_ptr->forward) {
746 	if (sig_ptr->copyof) {
747 	    /* Parent may have moved */
748 	    sig_ptr->bptr = sig_ptr->copyof->bptr;
749 	}
750 	/* re-initialize the cptr's to the bptr's */
751 	sig_ptr->cptr = sig_ptr->bptr;
752 	assert (sig_ptr->bptr->siglw.stbits.size!=0);
753     }
754 }
755 
fil_trace_end(Trace_t * trace)756 void fil_trace_end (
757     /* Perform stuff at end of trace - common across all reading routines */
758     Trace_t	*trace)
759 {
760     Signal_t	*sig_ptr;
761 
762     if (DTPRINT_FILE) printf ("In fil_trace_end\n");
763 
764     /* Modify ending cptrs to be correct */
765     fil_mark_cptr_end (trace);
766 
767     /* Misc */
768     trace->dispsig = trace->firstsig;
769 
770     /* Make sure time is within bounds */
771     if ( (global->time < trace->start_time) || (global->time > trace->end_time)) {
772 	global->time = trace->start_time;
773     }
774 
775     /* Mark as loaded */
776     trace->loaded = TRUE;
777 
778     switch (trace->dfile.fileformat) {
779     case	FF_TEMPEST:
780     case	FF_DECSIM_ASCII:
781     case	FF_DECSIM_BIN:
782 	sig_modify_enables (trace);
783 	break;
784     case	FF_VERILOG:
785     case	FF_VERILOG_VPD:
786     default:
787 	break;
788     }
789 
790     /* Create xstring of the name (to avoid calling again and again) */
791     for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_ptr->forward) {
792 	sig_ptr->xsigname = XmStringCreateSimple (sig_ptr->signame);
793     }
794 
795     /* Preserve file information */
796     sig_cross_restore (trace);
797 
798     /* Read .dino file stuff yet again to get signal_highlights */
799     /* Don't report errors, as they would pop up for a second time. */
800     config_read_defaults (trace, FALSE);
801 
802     /* Modify deleted trace to have latest options */
803     global->deleted_trace_head->dfile.hierarchy_separator = trace->dfile.hierarchy_separator;
804     global->deleted_trace_head->dfile.vector_separator = trace->dfile.hierarchy_separator;
805     global->deleted_trace_head->dfile.vectorend_separator = trace->dfile.vectorend_separator;
806 
807     /* Apply the statenames */
808     draw_needupd_val_states ();
809     draw_needupd_val_search ();
810     draw_needupd_sig_search ();
811     draw_needupd_sig_start ();
812     grid_calc_autos (trace);
813 
814     if (DTPRINT_FILE) printf ("fil_trace_end: Done\n");
815 }
816 
817 /****************************** MENU OPTIONS ******************************/
818 
trace_reread_all_cb(Widget w,Trace_t * trace)819 void trace_reread_all_cb (Widget w, Trace_t* trace) {
820     trace_reread_all();
821 }
trace_reread_cb(Widget w,Trace_t * trace)822 void trace_reread_cb (Widget w, Trace_t* trace) {
823     trace_reread (trace);
824 }
825