1 /******************************************************************************
2 * DESCRIPTION: Dinotrace source: value-at-a-time decoding
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 <Xm/Form.h>
60 #include <Xm/PushB.h>
61 #include <Xm/PushBG.h>
62 #include <Xm/ToggleB.h>
63 #include <Xm/SelectioB.h>
64 #include <Xm/Text.h>
65 #include <Xm/BulletinB.h>
66 #include <Xm/RowColumn.h>
67 #include <Xm/RowColumnP.h>
68 #include <Xm/Label.h>
69 #include <Xm/LabelP.h>
70 #include <Xm/MenuShellP.h>
71 #include <Xm/GrabShell.h>
72
73 #include "functions.h"
74
75 char *val_state_name[] = { "STATE_0", "STATE_1", "STATE_U", "STATE_Z",
76 "STATE_B32", "STATE_F32", "STATE_B128", "STATE_F128"};
77
78 /****************************** UTILITIES ******************************/
79
val_bit(const Value_t * value_ptr,int bit)80 static uint_t val_bit (
81 const Value_t *value_ptr,
82 int bit)
83 /* Return bit value, understanding 4-state, may be 0/1/U/Z */
84 {
85 int bitpos = bit & 0x1f;
86 if (bit<0) return(0);
87 switch (value_ptr->siglw.stbits.state) {
88 case STATE_0:
89 return (0);
90 case STATE_1:
91 return (bit==0 ? 1:0);
92 case STATE_Z:
93 return (3);
94 case STATE_B32:
95 if (bit<32) return ( (value_ptr->number[0] >>bitpos) & 1);
96 return (0);
97 case STATE_F32:
98 if (bit<32) return (( (value_ptr->number[0] >>bitpos) & 1)
99 | (((value_ptr->number[1] >>bitpos) & 1)<<1));
100 return (0);
101 case STATE_B128:
102 if (bit<32) return ( (value_ptr->number[0] >>bitpos) & 1);
103 if (bit<64) return ( (value_ptr->number[1] >>bitpos) & 1);
104 if (bit<96) return ( (value_ptr->number[2] >>bitpos) & 1);
105 if (bit<128) return ( (value_ptr->number[3] >>bitpos) & 1);
106 return (0);
107 case STATE_F128:
108 if (bit<32) return (( (value_ptr->number[0] >>bitpos) & 1)
109 | (((value_ptr->number[4] >>bitpos) & 1)<<1));
110 if (bit<64) return (( (value_ptr->number[1] >>bitpos) & 1)
111 | (((value_ptr->number[5] >>bitpos) & 1)<<1));
112 if (bit<96) return (( (value_ptr->number[2] >>bitpos) & 1)
113 | (((value_ptr->number[6] >>bitpos) & 1)<<1));
114 if (bit<128) return (( (value_ptr->number[3] >>bitpos) & 1)
115 | (((value_ptr->number[7] >>bitpos) & 1)<<1));
116 return (0);
117 default:
118 return (2);/*X*/
119 }
120 }
121
val_str_digit_ascii(const Value_t * value_ptr,int lsb)122 static char val_str_digit_ascii (
123 const Value_t *value_ptr,
124 int lsb)
125 {
126 uint_t val = 0;
127 uint_t bit;
128 int bitnum;
129
130 for (bitnum=lsb+7; bitnum>=lsb; bitnum--) {
131 bit = val_bit (value_ptr, bitnum);
132 if (bit>1) return ('X');
133 val = val<<1 | bit;
134 }
135 val &= 0xff;
136 if (val==0) return (' ');
137 if (!isprint(val)) return ('?');
138 return (val);
139 }
140
val_str_ascii(char * strg,const Value_t * value_ptr,Boolean_t compressed)141 static void val_str_ascii (
142 char *strg,
143 const Value_t *value_ptr,
144 Boolean_t compressed) /* Drawing on screen; keep small & tidy */
145 {
146 Boolean_t keepspace = FALSE;
147 char *cp = strg;
148 switch (value_ptr->siglw.stbits.state) {
149 case STATE_U:
150 *cp++ = 'x';
151 break;
152 case STATE_Z:
153 *cp++ = 'z';
154 break;
155 case STATE_0:
156 break;
157 default: {
158 int bitnum;
159 char c;
160 if (!compressed) *cp++ = '\"';
161 for (bitnum = 128-8; bitnum >= 0; bitnum-= 8) {
162 c = val_str_digit_ascii (value_ptr, bitnum);
163 if (c!=' ' || keepspace) {
164 *cp++ = c;
165 keepspace = FALSE;
166 }
167 }
168 while (cp>strg && *(cp-1) == ' ') cp--;
169 if (!compressed) *cp++ = '\"';
170 }
171 }
172 *cp++ = '\0';
173 }
174
val_str_digit(int lsb,uint_t mask,uint_t lw,uint_t enlw)175 static char val_str_digit (
176 int lsb,
177 uint_t mask,
178 uint_t lw,
179 uint_t enlw
180 )
181 {
182 lw = (lw>>lsb) & mask;
183 enlw = (enlw>>lsb) & mask;
184 if (enlw) {
185 if ((enlw == mask) && (lw == mask)) {
186 return ('z'); /* All z's */
187 } else if ((enlw == mask) && (lw == 0)) {
188 return ('x'); /* All u's */
189 }
190 return ('X'); /* U/Z/0/1 mix */
191 }
192
193 return (lw + ((lw < 10) ? '0':('a'-10)));
194 }
195
val_str_lw(const Radix_t * radix_ptr,char * strg,char sep,Boolean_t middle,int width,uint_t lw,uint_t enlw)196 static void val_str_lw (
197 const Radix_t *radix_ptr,
198 char *strg,
199 char sep,
200 Boolean_t middle, /* 2nd, 3rd, etc value on this line */
201 int width,
202 uint_t lw,
203 uint_t enlw
204 )
205 {
206 int bit = 31;
207
208 /* Separate if needed */
209 if (middle) {
210 *strg++ = sep;
211 }
212 if (!middle) {
213 if (width) {
214 /* Start at appropriate bit */
215 bit = ((width-1) & 31);
216 } else {
217 /* Skip leading 0's */
218 for (; bit>0; bit--) {
219 if ((lw|enlw) & (1L<<bit)) break;
220 }
221 }
222 }
223
224 switch (radix_ptr->type) {
225 case RADIX_HEX_UN:
226 for (; bit>=0; bit--) {
227 bit = (bit / 4) *4; /* Next hex digit */
228 *strg++ = val_str_digit (bit, 0xf, lw, enlw);
229 }
230 *strg++ = '\0';
231 break;
232 case RADIX_OCT_UN:
233 for (; bit>=0; bit--) {
234 bit = (bit / 3) *3; /* Next octal digit */
235 *strg++ = val_str_digit (bit, 0x7, lw, enlw);
236 }
237 *strg++ = '\0';
238 break;
239 case RADIX_DEC_UN:
240 if (enlw) {
241 strcpy (strg,"Mixed01XU");
242 } else {
243 sprintf (strg,middle?"%010d":"%d", lw);
244 }
245 break;
246 case RADIX_DEC_SN:
247 if (enlw) {
248 strcpy (strg,"Mixed01XU");
249 } else {
250 if (lw & (1<<(width-1))) { // Negative
251 int masked = ~lw & ((1<<(width-1))-1);
252 sprintf (strg,"-%d", masked+1);
253 } else { // Signed and positive
254 sprintf (strg,middle?"%010d":"%d", lw);
255 }
256 }
257 break;
258 case RADIX_BIN_UN: {
259 for (;bit>=0;bit--) {
260 *strg++ = val_str_digit (bit, 0x1, lw, enlw);
261 }
262 *strg++ = '\0';
263 break;
264 }
265 default: strcat (strg, "bad radix");
266 }
267 }
268
val_to_string(const Radix_t * radix_ptr,char * strg,const Value_t * value_ptr,int width,Boolean_t compressed,Boolean_t dropleading)269 void val_to_string (
270 const Radix_t *radix_ptr,
271 char *strg,
272 const Value_t *value_ptr,
273 int width, /* or 0 to drop leading 0s */
274 Boolean_t compressed, /* Drawing on screen; keep small & tidy */
275 Boolean_t dropleading) /* Drop leading spaces */
276 /* Convert a string to a value */
277 /* Understand 'h 'b and other similar tags */
278 /* Try to convert a signal state also */
279 /* This isn't fast, so don't use when reading files!!! */
280 {
281 char sep = compressed ? ' ' : '_';
282 if (radix_ptr==NULL) {strcpy (strg,"nullradix_ptr"); return;}
283
284 if (radix_ptr->type == RADIX_ASCII) {
285 val_str_ascii (strg, value_ptr, compressed);
286 return;
287 }
288
289 switch (value_ptr->siglw.stbits.state) {
290 case STATE_0:
291 *strg++ = '0';
292 break;
293 case STATE_1:
294 *strg++ = '1';
295 break;
296 case STATE_U:
297 *strg++ = 'x';
298 break;
299 case STATE_Z:
300 *strg++ = 'z';
301 break;
302
303 case STATE_B32:
304 case STATE_F32:
305 case STATE_B128:
306 case STATE_F128: {
307 Boolean_t middle = FALSE;
308 if (!compressed) {
309 strcpy (strg, radix_ptr->prefix);
310 strg += strlen (radix_ptr->prefix);
311 }
312 if (radix_ptr->type == RADIX_REAL
313 && value_ptr->siglw.stbits.state == STATE_B128) {
314 sprintf (strg, "%g", *(double*)(&value_ptr->number[0]));
315 } else {
316 uint_t enlw;
317 if (value_ptr->siglw.stbits.state == STATE_B128
318 || value_ptr->siglw.stbits.state == STATE_F128) {
319 if (value_ptr->number[3]
320 || (!dropleading && width>32*3)) {
321 val_str_lw (radix_ptr, strg, sep, middle, width,
322 value_ptr->number[3],
323 ((value_ptr->siglw.stbits.state == STATE_F128)
324 ?value_ptr->number[7]:0));
325 strg += strlen (strg);
326 middle = TRUE;
327 }
328 if (value_ptr->number[3] || value_ptr->number[2]
329 || (!dropleading && width>32*2)) {
330 val_str_lw (radix_ptr, strg, sep, middle, width,
331 value_ptr->number[2],
332 ((value_ptr->siglw.stbits.state == STATE_F128)
333 ?value_ptr->number[6]:0));
334 strg += strlen (strg);
335 middle = TRUE;
336 }
337 if (value_ptr->number[3] || value_ptr->number[2]
338 || value_ptr->number[1]
339 || (!dropleading && width>32*1)) {
340 val_str_lw (radix_ptr, strg, sep, middle, width,
341 value_ptr->number[1],
342 ((value_ptr->siglw.stbits.state == STATE_F128)
343 ?value_ptr->number[5]:0));
344 strg += strlen (strg);
345 middle = TRUE;
346 }
347 }
348 enlw = 0;
349 if (value_ptr->siglw.stbits.state == STATE_F128) {
350 enlw = value_ptr->number[4];
351 }
352 if (value_ptr->siglw.stbits.state == STATE_F32) {
353 enlw = value_ptr->number[1];
354 }
355 val_str_lw (radix_ptr, strg, sep, middle, width,
356 value_ptr->number[0], enlw);
357 }
358 strg += strlen (strg);
359 break;
360 }
361 default:
362 *strg++ = '?';
363 break;
364 }
365 *strg++ = '\0';
366 }
367
val_minimize(Value_t * value_ptr,Signal_t * sig_ptr)368 void val_minimize (
369 Value_t *value_ptr,
370 Signal_t *sig_ptr
371 )
372 /* Given a STATE_B128, try to shrink to something smaller if we can */
373 {
374 Boolean_t num123 = (value_ptr->number[1]
375 || value_ptr->number[2]
376 || value_ptr->number[3]);
377 Boolean_t num567 = (value_ptr->number[5]
378 || value_ptr->number[6]
379 || value_ptr->number[7]);
380 if (!value_ptr->number[4] && !num567) {
381 if (!num123) {
382 if (!value_ptr->number[0])
383 value_ptr->siglw.stbits.state = STATE_0;
384 else value_ptr->siglw.stbits.state = STATE_B32;
385 }
386 else value_ptr->siglw.stbits.state = STATE_B128;
387 } else {
388 if ((value_ptr->number[0] == value_ptr->number[4])
389 && (value_ptr->number[1] == value_ptr->number[5])
390 && (value_ptr->number[2] == value_ptr->number[6])
391 && (value_ptr->number[3] == value_ptr->number[7])
392 && sig_ptr
393 && (value_ptr->number[0] == sig_ptr->value_mask[0])
394 && (value_ptr->number[1] == sig_ptr->value_mask[1])
395 && (value_ptr->number[2] == sig_ptr->value_mask[2])
396 && (value_ptr->number[3] == sig_ptr->value_mask[3])
397 ) {
398 value_ptr->siglw.stbits.state = STATE_Z;
399 } else if (!num123 && !num567) {
400 value_ptr->siglw.stbits.state = STATE_F32;
401 value_ptr->number[1] = value_ptr->number[4];
402 value_ptr->number[4] = 0;
403 } else {
404 value_ptr->siglw.stbits.state = STATE_F128;
405 }
406 }
407 value_ptr->siglw.stbits.size = STATE_SIZE(value_ptr->siglw.stbits.state);
408 }
409
string_to_value(Radix_t ** radix_pptr,const char * strg,Value_t * value_ptr)410 void string_to_value (
411 Radix_t **radix_pptr,
412 const char *strg,
413 Value_t *value_ptr)
414 {
415 register char value;
416 uint_t MSO = (7L<<29); /* Most significant octal digit */
417 uint_t MSH = (15L<<28); /* Most significant hex digit */
418 uint_t MSB = (1L<<31); /* Most significant binary digit */
419 uint_t MSC = (0xffL<<24); /* Most significant char */
420 const char *cp = strg;
421 char radix_id;
422 uint_t *nptr = &(value_ptr->number[0]);
423 Boolean_t negate = FALSE;
424
425 val_zero (value_ptr);
426
427 radix_id = 'x';
428 *radix_pptr = global->radixs[RADIX_HEX_UN];
429 if (*cp=='\'') {
430 radix_id = cp[1];
431 cp+=2;
432 } else if (isalpha(*cp) && cp[1]=='"') {
433 radix_id = cp[0];
434 cp+=2;
435 } else if (*cp=='"') {
436 radix_id = cp[0];
437 cp++;
438 }
439 switch (toupper(radix_id)) {
440 case 'o': *radix_pptr = global->radixs[RADIX_OCT_UN]; break;
441 case 'd': *radix_pptr = global->radixs[RADIX_DEC_UN]; break;
442 case 'i': *radix_pptr = global->radixs[RADIX_DEC_SN]; break;
443 case 'b': *radix_pptr = global->radixs[RADIX_BIN_UN]; break;
444 case 'r': *radix_pptr = global->radixs[RADIX_REAL]; break;
445 case '"':
446 case 's':
447 *radix_pptr = global->radixs[RADIX_ASCII]; break;
448 default:
449 case 'h':
450 case 'x':
451 *radix_pptr = global->radixs[RADIX_HEX_UN]; break;
452 }
453
454 if ((*radix_pptr)->type != RADIX_ASCII
455 || (cp == strg)) {
456 /*Value literals: Not in a string, or unquoted:*/
457 if ((*cp == 'z' || *cp == 'Z') && cp[1]=='\0') {
458 value_ptr->siglw.stbits.state = STATE_Z;
459 return;
460 }
461 if ((*cp == 'u' || *cp == 'U' || *cp == 'x' || *cp == 'X') && cp[1]=='\0') {
462 value_ptr->siglw.stbits.state = STATE_U;
463 return;
464 }
465 }
466
467 if ((*radix_pptr)->type == RADIX_REAL) {
468 double dnum = atof (cp);
469 if (dnum == 0) value_ptr->siglw.stbits.state = STATE_0;
470 else {
471 value_ptr->siglw.stbits.state = STATE_B128;
472 *((double*)&value_ptr->number[0]) = dnum;
473 }
474 return;
475 }
476
477 for (; *cp; cp++) {
478 value = -1;
479 if (*cp >= '0' && *cp <= '9')
480 value = *cp - '0';
481 else if (*cp >= 'A' && *cp <= 'F')
482 value = *cp - ('A' - 10);
483 else if (*cp >= 'a' && *cp <= 'f')
484 value = *cp - ('a' - 10);
485 else if (*cp == '-')
486 negate = !negate;
487
488 switch ((*radix_pptr)->type) {
489 case RADIX_HEX_UN:
490 if (value >=0 && value <= 15) {
491 nptr[3] = (nptr[3]<<4) + ((nptr[2] & MSH)>>28);
492 nptr[2] = (nptr[2]<<4) + ((nptr[1] & MSH)>>28);
493 nptr[1] = (nptr[1]<<4) + ((nptr[0] & MSH)>>28);
494 nptr[0] = (nptr[0]<<4) + value;
495 }
496 break;
497 case RADIX_OCT_UN:
498 if (value >=0 && value <= 7) {
499 nptr[3] = (nptr[3]<<3) + ((nptr[2] & MSO)>>29);
500 nptr[2] = (nptr[2]<<3) + ((nptr[1] & MSO)>>29);
501 nptr[1] = (nptr[1]<<3) + ((nptr[0] & MSO)>>29);
502 nptr[0] = (nptr[0]<<3) + value;
503 }
504 break;
505 case RADIX_BIN_UN:
506 if (value >=0 && value <= 1) {
507 nptr[3] = (nptr[3]<<1) + ((nptr[2] & MSB)>>31);
508 nptr[2] = (nptr[2]<<1) + ((nptr[1] & MSB)>>31);
509 nptr[1] = (nptr[1]<<1) + ((nptr[0] & MSB)>>31);
510 nptr[0] = (nptr[0]<<1) + value;
511 }
512 break;
513 case RADIX_DEC_UN:
514 case RADIX_DEC_SN:
515 if (value >=0 && value <= 9) {
516 /* This is buggy for large numbers */
517 /* Note in spec that binary is for 32 bit or less numbers */
518 nptr[3] = (nptr[3]*10) + ((cp>=(strg+30))?cp[-30]:0);
519 nptr[2] = (nptr[2]*10) + ((cp>=(strg+20))?cp[-20]:0);
520 nptr[1] = (nptr[1]*10) + ((cp>=(strg+10))?cp[-10]:0);
521 nptr[0] = (nptr[0]*10) + value;
522 }
523 break;
524 case RADIX_ASCII:
525 if (*cp != '\"') {
526 nptr[3] = (nptr[3]<<8) + ((nptr[2] & MSC)>>24);
527 nptr[2] = (nptr[2]<<8) + ((nptr[1] & MSC)>>24);
528 nptr[1] = (nptr[1]<<8) + ((nptr[0] & MSC)>>24);
529 nptr[0] = (nptr[0]<<8) + (*cp & 0xff);
530 }
531 break;
532 case RADIX_MAX:
533 case RADIX_REAL:
534 break;
535 }
536 }
537
538 if (negate && (nptr[0] || nptr[1] || nptr[2] || nptr[3])) {
539 nptr[0] = ~nptr[0];
540 nptr[1] = ~nptr[1];
541 nptr[2] = ~nptr[2];
542 nptr[3] = ~nptr[3];
543 nptr[0]++;
544 if (!nptr[0]) nptr[1]++;
545 if (!nptr[0] && !nptr[1]) nptr[2]++;
546 if (!nptr[0] && !nptr[1] && !nptr[2]) nptr[3]++;
547 }
548
549 val_minimize (value_ptr, NULL);
550 }
551
val_zero_or_one(const Value_t * vptr)552 Boolean_t val_zero_or_one (
553 const Value_t *vptr)
554 {
555 return ( ( vptr->siglw.stbits.state == STATE_0)
556 || (vptr->siglw.stbits.state == STATE_1)
557 || (vptr->siglw.stbits.state == STATE_B32
558 && (vptr->number[0] == 1)));
559 }
560
val_equal(const Value_t * vptra,const Value_t * vptrb)561 Boolean_t val_equal (
562 const Value_t *vptra,
563 const Value_t *vptrb)
564 {
565 return ((vptra->siglw.stbits.state == vptrb->siglw.stbits.state)
566 && (( ( vptra->siglw.stbits.state == STATE_0)
567 | (vptra->siglw.stbits.state == STATE_1)
568 | (vptra->siglw.stbits.state == STATE_U)
569 | (vptra->siglw.stbits.state == STATE_Z))
570 || ((vptra->siglw.stbits.state == STATE_B32)
571 & (vptra->number[0] == vptrb->number[0]))
572 || ((vptra->siglw.stbits.state == STATE_B128)
573 & (vptra->number[0] == vptrb->number[0])
574 & (vptra->number[1] == vptrb->number[1])
575 & (vptra->number[2] == vptrb->number[2])
576 & (vptra->number[3] == vptrb->number[3]))
577 || ((vptra->siglw.stbits.state == STATE_F32)
578 & (vptra->number[0] == vptrb->number[0])
579 & (vptra->number[1] == vptrb->number[1]))
580 || ((vptra->siglw.stbits.state == STATE_F128)
581 & (vptra->number[0] == vptrb->number[0])
582 & (vptra->number[1] == vptrb->number[1])
583 & (vptra->number[2] == vptrb->number[2])
584 & (vptra->number[3] == vptrb->number[3])
585 & (vptra->number[4] == vptrb->number[4])
586 & (vptra->number[5] == vptrb->number[5])
587 & (vptra->number[6] == vptrb->number[6])
588 & (vptra->number[7] == vptrb->number[7]))
589 ));
590 }
591
val_update_search()592 void val_update_search ()
593 {
594 Trace_t *trace;
595 Signal_t *sig_ptr;
596 Value_t *cptr;
597 int cursorize;
598 register int i;
599 DCursor_t *csr_ptr;
600 Boolean_t any_enabled;
601 Boolean_t zero_or_one_search = FALSE;
602 Boolean_t matches[MAX_SRCH]; /* Cache the wildmat for each bit, so searching is faster */
603 static Boolean_t enabled_lasttime = FALSE;
604 int prev_cursor;
605
606 if (DTPRINT_ENTRY) printf ("In val_update_search\n");
607
608 /* This sometimes takes a while (don't XSync in case it doesn't) */
609 prev_cursor = last_set_cursor ();
610 set_cursor (DC_BUSY);
611
612 /* If no searches are enabled, skip the cptr loop. */
613 /* This saves 3% of the first reading time on large traces */
614 any_enabled = enabled_lasttime; /* if all get disabled, we still need to clean up enables */
615 for (i=0; i<MAX_SRCH; i++) {
616 if ((global->val_srch[i].color != 0)
617 || (global->val_srch[i].cursor != 0)) {
618 any_enabled = TRUE;
619 if (val_zero_or_one(&global->val_srch[i].value)) zero_or_one_search = TRUE;
620 }
621 }
622 enabled_lasttime = FALSE;
623
624 /* Mark all cursors that are a result of a search as old (-1) */
625 for (csr_ptr = global->cursor_head; csr_ptr; csr_ptr = csr_ptr->next) {
626 if (csr_ptr->type==SEARCH) csr_ptr->type = SEARCHOLD;
627 }
628
629 /* Search every trace for the value, mark the signal if it has it to speed up displaying */
630 for (trace = global->deleted_trace_head; trace; trace = trace->next_trace) {
631 for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_ptr->forward) {
632 if (any_enabled) {
633 if (!zero_or_one_search && sig_ptr->bits<2) {
634 /* Single bit signal, don't search for values > 1 for speed */
635 continue;
636 }
637
638 cursorize=0;
639 for (i=0; i<MAX_SRCH; i++) {
640 matches[i] = 0;
641 }
642
643 for (cptr = sig_ptr->bptr; (CPTR_TIME(cptr) != EOT);
644 cptr = CPTR_NEXT(cptr)) {
645 int color_to_assign = 0;
646 switch (cptr->siglw.stbits.state) {
647 case STATE_0:
648 case STATE_1:
649 if (!zero_or_one_search) break;
650 /* FALLTHRU */
651 case STATE_B32:
652 case STATE_B128:
653 case STATE_F32:
654 case STATE_F128:
655 for (i=0; i<MAX_SRCH; i++) {
656 if (val_equal (cptr, &global->val_srch[i].value)
657 && ( matches[i] || wildmat (sig_ptr->signame, global->val_srch[i].signal)) ) {
658 matches[i] = TRUE;
659 if ( global->val_srch[i].color != 0) {
660 color_to_assign = global->val_srch[i].color;
661 enabled_lasttime = TRUE;
662 }
663 if ( global->val_srch[i].cursor != 0) {
664 cursorize = global->val_srch[i].cursor;
665 enabled_lasttime = TRUE;
666 }
667 /* don't break, because if same value on two lines, one with cursor and one without will fail */
668 }
669 }
670 break;
671 } /* switch */
672
673 if (color_to_assign != (int)cptr->siglw.stbits.color) {
674 /* Don't write unless changes to save cache flushing */
675 cptr->siglw.stbits.color = color_to_assign;
676 }
677
678 if (cursorize) {
679 if (NULL != (csr_ptr = time_to_cursor (CPTR_TIME(cptr)))) {
680 if (csr_ptr->type == SEARCHOLD) {
681 /* mark the old cursor as new so won't be deleted */
682 csr_ptr->type = SEARCH;
683 }
684 }
685 else {
686 /* Make new cursor at this location */
687 cur_new (CPTR_TIME(cptr), cursorize, SEARCH, NULL);
688 }
689 cursorize = 0;
690 }
691
692 } /* for cptr */
693 } /* if enabled */
694 } /* for sig */
695 } /* for trace */
696
697 /* Delete all old cursors */
698 cur_delete_of_type (SEARCHOLD);
699
700 set_cursor (prev_cursor);
701 }
702
val_transition_cnt(Signal_t * sig_ptr,Value_t * stop_cptr,int * negedgesp,int * posedgesp)703 void val_transition_cnt (Signal_t* sig_ptr, Value_t* stop_cptr, int* negedgesp, int* posedgesp)
704 {
705 Value_t* cptr;
706 int posedges = 0;
707 int negedges = 0;
708 int last_state = -1;
709 for (cptr = sig_ptr->bptr; (CPTR_TIME(cptr) != EOT); cptr = CPTR_NEXT(cptr)) {
710 /**/
711 switch (cptr->siglw.stbits.state) {
712 case STATE_0:
713 if (last_state==STATE_1 || last_state<0) negedges++;
714 break;
715 case STATE_1:
716 if (last_state==STATE_0 || last_state<0) posedges++;
717 break;
718 case STATE_Z:
719 case STATE_B32:
720 case STATE_B128:
721 case STATE_F32:
722 case STATE_F128:
723 break;
724 }
725 last_state = cptr->siglw.stbits.state;
726 if (cptr == stop_cptr) break;
727 }
728 *negedgesp = negedges;
729 *posedgesp = posedges;
730 }
731
732 /****************************** RADIXS ******************************/
733
val_radix_find(const char * name)734 Radix_t *val_radix_find (
735 const char *name)
736 {
737 Radix_t *radix_ptr;
738 for (radix_ptr=global->radixs[0]; radix_ptr; radix_ptr = radix_ptr->next) {
739 if (!strcasecmp(radix_ptr->name, name)) {
740 return (radix_ptr);
741 }
742 }
743 return (NULL);
744 }
745
val_radix_add(RadixType_t type,const char * name,const char * prefix)746 static Radix_t *val_radix_add (
747 RadixType_t type,
748 const char *name,
749 const char *prefix)
750 {
751 int radixnum;
752 Radix_t *radix_ptr;
753 Radix_t *found_radix_ptr;
754
755 found_radix_ptr = val_radix_find (name); /* Null if not found */
756 radix_ptr = found_radix_ptr;
757
758 if (found_radix_ptr == NULL) {
759 Radix_t *radix_end_ptr;
760 radix_ptr = DNewCalloc (Radix_t);
761
762 for (radix_end_ptr=global->radixs[0]; radix_end_ptr; radix_end_ptr = radix_end_ptr->next) {
763 if (!radix_end_ptr->next) {
764 radix_end_ptr->next = radix_ptr;
765 break;
766 }
767 }
768
769 /* Can we fit it in the menu? */
770 for (radixnum=0; radixnum < RADIX_MAX_MENU; radixnum++) {
771 if (global->radixs[radixnum]==NULL) {
772 global->radixs[radixnum]=radix_ptr;
773 break;
774 }
775 }
776 }
777 radix_ptr->name = strdup (name);
778 radix_ptr->type = type;
779 radix_ptr->prefix = strdup(prefix);
780
781 return (radix_ptr);
782 }
783
val_radix_init()784 void val_radix_init ()
785 {
786 int radixnum;
787 /* Define default radixs */
788 for (radixnum=0; radixnum<RADIX_MAX; radixnum++) {
789 global->radixs[radixnum] = NULL;
790 }
791 /* This order MUST match the enum order of RadixType_t */
792 /* The first one listed is the system default */
793 #define DEFAULT_RADIX_PREFIX "'h"
794 val_radix_add (RADIX_HEX_UN, "Hex", "");
795 val_radix_add (RADIX_OCT_UN, "Octal", "'o");
796 val_radix_add (RADIX_BIN_UN, "Binary", "'b");
797 val_radix_add (RADIX_DEC_UN, "Decimal", "'d");
798 val_radix_add (RADIX_DEC_SN, "Signed Decimal", "'i");
799 val_radix_add (RADIX_ASCII, "Ascii", "\"");
800 val_radix_add (RADIX_REAL, "Real", "'r");
801 }
802
803 /****************************** STATES ******************************/
804
val_states_update()805 void val_states_update ()
806 {
807 Trace_t *trace;
808 Signal_t *sig_ptr;
809
810 if (DTPRINT_ENTRY) printf ("In val_states_update\n");
811
812 for (trace = global->deleted_trace_head; trace; trace = trace->next_trace) {
813 for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_ptr->forward) {
814 if (NULL != (sig_ptr->decode = signalstate_find (trace, sig_ptr->signame))) {
815 /* if (DTPRINT_FILE) printf ("Signal %s is patterned\n",sig_ptr->signame); */
816 }
817 }
818 }
819 }
820
821
822 /****************************** MENU OPTIONS ******************************/
823
val_examine_cb(Widget w)824 void val_examine_cb (
825 Widget w)
826 {
827 Trace_t *trace = widget_to_trace(w);
828
829 if (DTPRINT_ENTRY) printf ("In val_examine_cb - trace=%p\n",trace);
830
831 /* process all subsequent button presses as cursor moves */
832 remove_all_events (trace);
833 set_cursor (DC_VAL_EXAM);
834 add_event (ButtonPressMask, val_examine_ev);
835 }
836
val_highlight_cb(Widget w)837 void val_highlight_cb (
838 Widget w)
839 {
840 Trace_t *trace = widget_to_trace(w);
841 if (DTPRINT_ENTRY) printf ("In val_highlight_cb - trace=%p\n",trace);
842
843 /* Grab color number from the menu button pointer */
844 global->highlight_color = submenu_to_color (trace, w, 0, trace->menu.val_highlight_pds);
845
846 /* process all subsequent button presses as signal deletions */
847 remove_all_events (trace);
848 set_cursor (DC_VAL_HIGHLIGHT);
849 add_event (ButtonPressMask, val_highlight_ev);
850 }
851
852
853 /****************************** EVENTS ******************************/
854
val_examine_string(Trace_t * trace,Signal_t * sig_ptr,DTime_t time)855 char *val_examine_string (
856 /* Return string with examine information in it */
857 Trace_t *trace,
858 Signal_t *sig_ptr,
859 DTime_t time)
860 {
861 Value_t *cptr;
862 static char strg[2000];
863 char strg2[2000];
864 int rows, cols, bit, row, col;
865 int lesser_index, greater_index;
866 char *format;
867
868 if (DTPRINT_ENTRY) printf ("\ttime = %d, signal = %s\n", time, sig_ptr->signame);
869
870 /* Get information */
871 cptr = value_at_time (sig_ptr, time);
872
873 lesser_index = MIN(sig_ptr->msb_index,sig_ptr->lsb_index);
874 greater_index = MAX(sig_ptr->msb_index,sig_ptr->lsb_index);
875 strcpy (strg, sig_ptr->signame);
876
877 if (CPTR_TIME(cptr) == EOT) {
878 strcat (strg, "\nValue at EOT:\n");
879 }
880 else {
881 strcat (strg, "\nValue at times ");
882 time_to_string (trace, strg2, CPTR_TIME(cptr), FALSE);
883 strcat (strg, strg2);
884 strcat (strg, " - ");
885 time_to_string (trace, strg2, CPTR_TIME(CPTR_NEXT(cptr)), FALSE);
886 strcat (strg, strg2);
887 strcat (strg, ":\n");
888 }
889
890 strcat (strg, "= ");
891 val_to_string (sig_ptr->radix, strg2, cptr, sig_ptr->bits, FALSE, FALSE);
892 strcat (strg, strg2);
893 strcat (strg, "\n");
894 if (sig_ptr->radix->type != global->radixs[0]->type) {
895 strcat (strg, "= ");
896 strcat (strg, DEFAULT_RADIX_PREFIX);
897 val_to_string (global->radixs[0], strg2, cptr, sig_ptr->bits, FALSE, FALSE);
898 strcat (strg, strg2);
899 strcat (strg, "\n");
900 }
901
902 if (sig_ptr->bits>1
903 && (lesser_index > 0)
904 && ((sig_ptr->bits + lesser_index) <= 32)
905 && (cptr->siglw.stbits.state == STATE_B32)) {
906 Value_t shifted;
907 val_zero (&shifted);
908 (&shifted)->siglw = cptr->siglw;
909 (&shifted)->number[0] = cptr->number[0] << lesser_index;
910 /* Show decode */
911 sprintf (strg2, "[%d:0] = ", greater_index);
912 strcat (strg, strg2);
913 val_to_string (sig_ptr->radix, strg2, &shifted,
914 sig_ptr->bits + lesser_index, FALSE, FALSE);
915 strcat (strg, strg2);
916 strcat (strg, "\n");
917 }
918
919 if (sig_ptr->bits>1
920 && (cptr->siglw.stbits.state == STATE_B32
921 || cptr->siglw.stbits.state == STATE_0)) {
922 uint_t num0 = 0;
923 if (cptr->siglw.stbits.state != STATE_0) num0 = cptr->number[0];
924 if ((sig_ptr->decode != NULL)
925 && (num0 < sig_ptr->decode->numstates)
926 && (sig_ptr->decode->statename[num0][0] != '\0') ) {
927 /* Show decode */
928 sprintf (strg2, "State = %s\n", sig_ptr->decode->statename[num0] );
929 strcat (strg, strg2);
930 }
931 }
932
933 switch (cptr->siglw.stbits.state) {
934 case STATE_B32:
935 case STATE_F32:
936 case STATE_B128:
937 case STATE_F128:
938 /* Bitwise information */
939 rows = (int)(ceil (sqrt ((double)(sig_ptr->bits))));
940 cols = (int)(ceil ((double)(rows) / 4.0) * 4);
941 rows = (int)(ceil ((double)(sig_ptr->bits)/ (double)cols));
942
943 format = "[%01d]=%c ";
944 if (greater_index >= 10) format = "[%02d]=%c ";
945 if (greater_index >= 100) format = "[%03d]=%c ";
946
947 bit = 0;
948 for (row=rows - 1; row >= 0; row--) {
949 for (col = cols - 1; col >= 0; col--) {
950 bit = (row * cols + col);
951 if ((bit>=0) && (bit < sig_ptr->bits)) {
952 uint_t bit_value = val_bit (cptr, bit);
953 sprintf (strg2, format, greater_index +
954 ((greater_index >= lesser_index)
955 ? (bit - sig_ptr->bits + 1) : (sig_ptr->bits - bit - 1)),
956 "01uz"[bit_value]);
957 strcat (strg, strg2);
958 if (col==4 || col==8) strcat (strg, " ");
959 }
960 }
961 strcat (strg, "\n");
962 }
963 break;
964 }
965
966 if (sig_ptr->bits > 2) {
967 int par = 0;
968 Boolean_t unknown = FALSE;
969 for (bit=0; bit<=sig_ptr->bits; bit++) {
970 uint_t bit_value = val_bit (cptr, bit);
971 if (bit_value==0 || bit_value==1) par ^= bit_value;
972 else unknown = TRUE;
973 }
974 if (!unknown) {
975 if (par) strcat (strg, "Odd Parity\n");
976 else strcat (strg, "Even Parity\n");
977 }
978 }
979
980 if (sig_ptr->bits == 1) {
981 int posedges = 0;
982 int negedges = 0;
983 val_transition_cnt (sig_ptr, cptr, &negedges, &posedges);
984 if (posedges && posedges>negedges) {
985 sprintf (strg2, "Posedge # %d\n", posedges);
986 strcat (strg, strg2);
987 } else if (negedges) {
988 sprintf (strg2, "Negedge # %d\n", negedges);
989 strcat (strg, strg2);
990 }
991 }
992
993 /* Debugging information */
994 if (DTDEBUG) {
995 strcat (strg, "\n");
996 sprintf (strg2, "Value_stbits %08x %s\n",
997 cptr->siglw.number,
998 val_state_name[cptr->siglw.stbits.state]);
999 strcat (strg, strg2);
1000 }
1001
1002 return (strg);
1003 }
1004
val_examine_popdown(Trace_t * trace)1005 static void val_examine_popdown (
1006 Trace_t *trace)
1007 {
1008 if (trace->examine.popup) {
1009 XtPopdown (trace->examine.popup);
1010 if (XtIsManaged(trace->examine.rowcol)) {
1011 XtUnmanageChild (trace->examine.label);
1012 XtUnmanageChild (trace->examine.rowcol);
1013 }
1014
1015 /* We'll regenerate, as the text gets hosed elsewise */
1016 XtDestroyWidget (trace->examine.label);
1017 XtDestroyWidget (trace->examine.rowcol);
1018 XtDestroyWidget (trace->examine.popup);
1019 trace->examine.popup = NULL;
1020 }
1021 }
1022
val_examine_popup(Trace_t * trace,XButtonPressedEvent * ev)1023 static void val_examine_popup (
1024 /* Create the popup menu for val_examine, based on cursor position x,y */
1025 Trace_t *trace,
1026 XButtonPressedEvent *ev)
1027 {
1028 DTime_t time;
1029 Signal_t *sig_ptr;
1030 char *strg = "No information here";
1031 XmString xs;
1032 int x,y; /* Must allow signed */
1033
1034 time = posx_to_time (trace, ev->x);
1035 sig_ptr = posy_to_signal (trace, ev->y);
1036 if (DTPRINT_ENTRY) printf ("In val_examine_popup %d %d time %d\n", __LINE__, ev->x, time);
1037
1038 val_examine_popdown (trace);
1039
1040 /* Get the text to display */
1041 /* Brace yourself for something that should be object oriented... */
1042 if (sig_ptr) {
1043 /* Get information */
1044 if (time>=0) {
1045 strg = val_examine_string (trace, sig_ptr, time);
1046 } else {
1047 strg = sig_examine_string (trace, sig_ptr);
1048 }
1049 } else {
1050 if (ev->y <= trace->ystart) {
1051 DTime_t grid_time;
1052 Grid_t *grid_ptr = posx_to_grid (trace, ev->x, &grid_time);
1053 if (grid_ptr) strg = grid_examine_string (trace, grid_ptr, grid_time);
1054 } else {
1055 DCursor_t *csr_ptr = posx_to_cursor (trace, ev->x);
1056 if (csr_ptr) strg = cur_examine_string (trace, csr_ptr);
1057 }
1058 }
1059
1060
1061 /* First, a override for the shell */
1062 /* It's probably tempting to use XmCreatePopupMenu. */
1063 /* Don't. It was that way, but the keyboard grab proved problematic */
1064 /* Don't manage this guy, he's just a container */
1065 XtSetArg (arglist[0], XmNallowShellResize, FALSE);
1066 XtSetArg (arglist[1], XmNshadowThickness, 2);
1067 #if 1 /* If you get a error on the next line, try changing the 1 to a 0 */
1068 trace->examine.popup = (Widget)XmCreateGrabShell (trace->main, "examinepopup", arglist, 2);
1069 #else
1070 trace->examine.popup = XtCreatePopupShell
1071 ("examinepopup", overrideShellWidgetClass, trace->main, arglist, 1);
1072 #endif
1073
1074 /* Row column for a nice border */
1075 /* For Lesstif we used to have MENU_POPUP, but that has mouse side effects */
1076 XtSetArg (arglist[0], XmNrowColumnType, XmWORK_AREA);
1077 XtSetArg (arglist[1], XmNborderWidth, 1);
1078 XtSetArg (arglist[2], XmNentryAlignment, XmALIGNMENT_CENTER);
1079 XtSetArg (arglist[3], XmNshadowThickness, 2);
1080 trace->examine.rowcol = XmCreateRowColumn (trace->examine.popup,"rowcol",arglist,4);
1081
1082 /* Finally the label */
1083 xs = string_create_with_cr (strg);
1084 XtSetArg (arglist[0], XmNlabelString, xs);
1085 trace->examine.label = XmCreateLabel (trace->examine.rowcol,"popuplabel",arglist,1);
1086 DManageChild (trace->examine.label, trace, MC_GLOBALKEYS);
1087 XmStringFree (xs);
1088
1089 /* Don't stretch past right screen edge if possible */
1090 x = ev->x_root; y = ev->y_root;
1091 if (x + trace->examine.label->core.width >= (XtScreen(trace->examine.popup)->width)) {
1092 x = (XtScreen(trace->examine.popup)->width) - trace->examine.label->core.width - 1;
1093 }
1094 if (y + trace->examine.label->core.height >= (XtScreen(trace->examine.popup)->height)) {
1095 y = (XtScreen(trace->examine.popup)->height) - trace->examine.label->core.height - 1;
1096 }
1097 x = MAX(x,0); y = MAX(y,0);
1098 XtSetArg (arglist[0], XmNx, x);
1099 XtSetArg (arglist[1], XmNy, y);
1100 XtSetValues (trace->examine.popup, arglist, 2);
1101
1102 /* Putem up */
1103 DManageChild (trace->examine.rowcol, trace, MC_GLOBALKEYS);
1104 XtPopup (trace->examine.popup, XtGrabNone); /* Don't manage! */
1105
1106 /* Make sure we find out when button gets released */
1107 XSelectInput (XtDisplay (trace->work),XtWindow (trace->examine.popup),
1108 ButtonReleaseMask|PointerMotionMask|StructureNotifyMask|ExposureMask);
1109
1110 /* We definately shouldn't have to force exposure of the popup. */
1111 /* However, the reality is lessTif doesn't seem to draw the text unless we do */
1112 /* This is a unknown bug in lessTif; it works fine on the true Motif */
1113 (xmRowColumnClassRec.core_class.expose) (trace->examine.rowcol, (XEvent*) ev, NULL);
1114 (xmLabelClassRec.core_class.expose) (trace->examine.label, (XEvent*) ev, NULL);
1115 }
1116
val_examine_ev(Widget w,Trace_t * trace,XButtonPressedEvent * ev)1117 void val_examine_ev (
1118 Widget w,
1119 Trace_t *trace,
1120 XButtonPressedEvent *ev)
1121 {
1122 XEvent event;
1123 XButtonPressedEvent *em;
1124 int update_pending = FALSE;
1125
1126 if (DTPRINT_ENTRY) printf ("In val_examine_ev, button=%d state=%d\n", ev->button, ev->state);
1127 if (ev->type != ButtonPress) return; /* Used for both button 1 & 2. */
1128
1129 /* not sure why this has to be done but it must be done */
1130 XSync (global->display, FALSE);
1131 XUngrabPointer (XtDisplay (trace->work),CurrentTime);
1132
1133 /* select the events the widget will respond to */
1134 XSelectInput (XtDisplay (trace->work),XtWindow (trace->work),
1135 ButtonReleaseMask|PointerMotionMask|StructureNotifyMask|ExposureMask);
1136
1137 /* Create */
1138 val_examine_popup (trace, ev);
1139
1140 /* loop and service events until button is released */
1141 while ( 1 ) {
1142 /* wait for next event */
1143 XNextEvent (global->display, &event);
1144 /* if (DTPRINT) { printf ("[ExEvent %s] ", events[ev->type]);fflush(stdout); } */
1145
1146 /* Mark an update as needed */
1147 if (event.type == MotionNotify) {
1148 update_pending = TRUE;
1149 }
1150
1151 /* if window was exposed, must redraw it */
1152 if (event.type == Expose) win_expose_cb (0,trace);
1153 /* if window was resized, must redraw it */
1154 if (event.type == ConfigureNotify) win_resize_cb (0,trace);
1155
1156 /* button released - calculate cursor position and leave the loop */
1157 if (event.type == ButtonRelease || event.type == ButtonPress) {
1158 /* ButtonPress in case user is freaking out, some strange X behavior caused the ButtonRelease to be lost */
1159 break;
1160 }
1161
1162 /* If a update is needed, redraw the menu. */
1163 /* Do it later if events pending, otherwise dragging is SLOWWWW */
1164 if (update_pending && !XPending (global->display)) {
1165 update_pending = FALSE;
1166 em = (XButtonPressedEvent *)&event;
1167 val_examine_popup (trace, em);
1168 }
1169
1170 if (global->redraw_needed && !XtAppPending (global->appcontext)) {
1171 draw_perform();
1172 }
1173 }
1174
1175 /* reset the events the widget will respond to */
1176 XSync (global->display, FALSE);
1177 XSelectInput (XtDisplay (trace->work),XtWindow (trace->work),
1178 ButtonPressMask|StructureNotifyMask|ExposureMask);
1179
1180 /* unmanage popup */
1181 val_examine_popdown (trace);
1182 draw_needed (trace);
1183 }
1184
val_examine_popup_act(Widget w,XButtonPressedEvent * ev,String params,Cardinal * num_params)1185 void val_examine_popup_act (
1186 Widget w,
1187 XButtonPressedEvent *ev,
1188 String params,
1189 Cardinal *num_params)
1190 {
1191 Trace_t *trace; /* Display information */
1192 int prev_cursor;
1193
1194 if (ev->type != ButtonPress) return;
1195
1196 if (DTPRINT_ENTRY) printf ("In val_examine_popup_ev, button=%d state=%d\n", ev->button, ev->state);
1197
1198 if (!(trace = widget_to_trace (w))) return;
1199
1200 /* Create */
1201 prev_cursor = last_set_cursor ();
1202 set_cursor (DC_VAL_EXAM);
1203
1204 val_examine_ev (w, trace, ev);
1205
1206 set_cursor (prev_cursor);
1207 }
1208
val_search_widget_update(Trace_t * trace)1209 static void val_search_widget_update (
1210 Trace_t *trace)
1211 {
1212 VSearchNum_t search_pos;
1213 char strg[MAXVALUELEN];
1214
1215 /* Copy settings to local area to allow cancel to work */
1216 for (search_pos=0; search_pos<MAX_SRCH; search_pos++) {
1217 ValSearch_t *vs_ptr = &global->val_srch[search_pos];
1218
1219 /* Update with current search enables */
1220 XtSetArg (arglist[0], XmNset, (vs_ptr->color != 0));
1221 XtSetValues (trace->value.enable[search_pos], arglist, 1);
1222
1223 /* Update with current cursor enables */
1224 XtSetArg (arglist[0], XmNset, (vs_ptr->cursor != 0));
1225 XtSetValues (trace->value.cursor[search_pos], arglist, 1);
1226
1227 /* Update with current search values */
1228 val_to_string (vs_ptr->radix, strg, &vs_ptr->value, 0, FALSE, TRUE);
1229 XmTextSetString (trace->value.text[search_pos], strg);
1230
1231 /* Update with current signal values */
1232 XmTextSetString (trace->value.signal[search_pos], vs_ptr->signal);
1233 }
1234 }
1235
val_search_cb(Widget w)1236 void val_search_cb (
1237 Widget w)
1238 {
1239 Trace_t *trace = widget_to_trace(w);
1240 int i;
1241
1242 if (DTPRINT_ENTRY) printf ("In val_search_cb - trace=%p\n",trace);
1243
1244 if (!trace->value.dialog) {
1245 XtSetArg (arglist[0], XmNdefaultPosition, TRUE);
1246 XtSetArg (arglist[1], XmNdialogTitle, XmStringCreateSimple ("Value Search Requester") );
1247 XtSetArg (arglist[2], XmNverticalSpacing, 7);
1248 XtSetArg (arglist[3], XmNhorizontalSpacing, 10);
1249 trace->value.dialog = XmCreateFormDialog (trace->work,"search",arglist,4);
1250
1251 XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple ("Color"));
1252 XtSetArg (arglist[1], XmNleftAttachment, XmATTACH_FORM );
1253 XtSetArg (arglist[2], XmNtopAttachment, XmATTACH_FORM );
1254 trace->value.label1 = XmCreateLabel (trace->value.dialog,"label1",arglist,3);
1255 DManageChild (trace->value.label1, trace, MC_NOKEYS);
1256
1257 XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple ("Place"));
1258 XtSetArg (arglist[1], XmNleftAttachment, XmATTACH_WIDGET );
1259 XtSetArg (arglist[2], XmNleftWidget, trace->value.label1);
1260 XtSetArg (arglist[3], XmNtopAttachment, XmATTACH_FORM );
1261 trace->value.label2 = XmCreateLabel (trace->value.dialog,"label2",arglist,4);
1262 DManageChild (trace->value.label2, trace, MC_NOKEYS);
1263
1264 XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple ("Value"));
1265 XtSetArg (arglist[1], XmNleftAttachment, XmATTACH_FORM );
1266 XtSetArg (arglist[2], XmNtopAttachment, XmATTACH_WIDGET );
1267 XtSetArg (arglist[3], XmNtopWidget, trace->value.label1);
1268 trace->value.label4 = XmCreateLabel (trace->value.dialog,"label4",arglist,4);
1269 DManageChild (trace->value.label4, trace, MC_NOKEYS);
1270
1271 XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple ("Cursor"));
1272 XtSetArg (arglist[1], XmNleftAttachment, XmATTACH_WIDGET );
1273 XtSetArg (arglist[2], XmNleftWidget, trace->value.label4);
1274 XtSetArg (arglist[3], XmNtopAttachment, XmATTACH_WIDGET );
1275 XtSetArg (arglist[4], XmNtopWidget, trace->value.label2);
1276 trace->value.label5 = XmCreateLabel (trace->value.dialog,"label5",arglist,5);
1277 DManageChild (trace->value.label5, trace, MC_NOKEYS);
1278
1279 XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple (
1280 "Search value, Hex default, 'd=decimal, 'b=binary"));
1281 XtSetArg (arglist[1], XmNleftAttachment, XmATTACH_WIDGET );
1282 XtSetArg (arglist[2], XmNleftWidget, trace->value.label5);
1283 XtSetArg (arglist[3], XmNtopAttachment, XmATTACH_WIDGET );
1284 XtSetArg (arglist[4], XmNtopWidget, trace->value.label1);
1285 trace->value.label3 = XmCreateLabel (trace->value.dialog,"label3",arglist,5);
1286 DManageChild (trace->value.label3, trace, MC_NOKEYS);
1287
1288 XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple ("Signal Wildcard"));
1289 XtSetArg (arglist[1], XmNrightAttachment, XmATTACH_FORM);
1290 XtSetArg (arglist[2], XmNtopAttachment, XmATTACH_WIDGET );
1291 XtSetArg (arglist[3], XmNtopWidget, trace->value.label1);
1292 trace->value.label6 = XmCreateLabel (trace->value.dialog,"label6",arglist,4);
1293 DManageChild (trace->value.label6, trace, MC_NOKEYS);
1294
1295 for (i=0; i<MAX_SRCH; i++) {
1296 /* enable button */
1297 XtSetArg (arglist[0], XmNleftAttachment, XmATTACH_FORM);
1298 XtSetArg (arglist[1], XmNselectColor, trace->xcolornums[i+1]);
1299 XtSetArg (arglist[2], XmNlabelString, XmStringCreateSimple (" "));
1300 XtSetArg (arglist[3], XmNtopAttachment, XmATTACH_WIDGET );
1301 XtSetArg (arglist[4], XmNtopWidget, ((i==0)?(trace->value.label4):(trace->value.signal[i-1])));
1302 trace->value.enable[i] = XmCreateToggleButton (trace->value.dialog,"togglen",arglist,5);
1303 DManageChild (trace->value.enable[i], trace, MC_NOKEYS);
1304
1305 /* enable button */
1306 XtSetArg (arglist[0], XmNselectColor, trace->xcolornums[i+1]);
1307 XtSetArg (arglist[1], XmNlabelString, XmStringCreateSimple (" "));
1308 XtSetArg (arglist[2], XmNtopAttachment, XmATTACH_WIDGET );
1309 XtSetArg (arglist[3], XmNtopWidget, ((i==0)?(trace->value.label4):(trace->value.signal[i-1])));
1310 XtSetArg (arglist[4], XmNleftAttachment, XmATTACH_WIDGET );
1311 XtSetArg (arglist[5], XmNleftWidget, trace->value.enable[i]);
1312 trace->value.cursor[i] = XmCreateToggleButton (trace->value.dialog,"cursorn",arglist,6);
1313 DManageChild (trace->value.cursor[i], trace, MC_NOKEYS);
1314
1315 /* create the file name text widget */
1316 XtSetArg (arglist[0], XmNrows, 1);
1317 XtSetArg (arglist[1], XmNcolumns, MAXVALUELEN);
1318 XtSetArg (arglist[2], XmNresizeHeight, FALSE);
1319 XtSetArg (arglist[3], XmNeditMode, XmSINGLE_LINE_EDIT);
1320 XtSetArg (arglist[4], XmNtopAttachment, XmATTACH_WIDGET );
1321 XtSetArg (arglist[5], XmNtopWidget, ((i==0)?(trace->value.label4):(trace->value.signal[i-1])));
1322 XtSetArg (arglist[6], XmNleftAttachment, XmATTACH_WIDGET );
1323 XtSetArg (arglist[7], XmNleftOffset, 20);
1324 XtSetArg (arglist[8], XmNleftWidget, trace->value.cursor[i]);
1325 trace->value.text[i] = XmCreateText (trace->value.dialog,"textn",arglist,9);
1326 DAddCallback (trace->value.text[i], XmNactivateCallback, val_search_ok_cb, trace);
1327 DManageChild (trace->value.text[i], trace, MC_NOKEYS);
1328
1329 /* create the signal text widget */
1330 XtSetArg (arglist[0], XmNrows, 1);
1331 XtSetArg (arglist[1], XmNcolumns, 30);
1332 XtSetArg (arglist[2], XmNresizeHeight, FALSE);
1333 XtSetArg (arglist[3], XmNeditMode, XmSINGLE_LINE_EDIT);
1334 XtSetArg (arglist[4], XmNtopAttachment, XmATTACH_WIDGET );
1335 XtSetArg (arglist[5], XmNtopWidget, ((i==0)?(trace->value.label4):(trace->value.signal[i-1])));
1336 XtSetArg (arglist[6], XmNleftAttachment, XmATTACH_WIDGET );
1337 XtSetArg (arglist[7], XmNleftOffset, 20);
1338 XtSetArg (arglist[8], XmNleftWidget, trace->value.text[i]);
1339 XtSetArg (arglist[9], XmNrightAttachment, XmATTACH_FORM );
1340 trace->value.signal[i] = XmCreateText (trace->value.dialog,"texts",arglist,10);
1341 DAddCallback (trace->value.signal[i], XmNactivateCallback, val_search_ok_cb, trace);
1342 DManageChild (trace->value.signal[i], trace, MC_NOKEYS);
1343 }
1344
1345 /* Ok/apply/cancel */
1346 ok_apply_cancel (&trace->value.okapply, trace->value.dialog,
1347 dmanage_last,
1348 (XtCallbackProc)val_search_ok_cb, trace,
1349 (XtCallbackProc)val_search_apply_cb, trace,
1350 NULL,NULL,
1351 (XtCallbackProc)unmanage_cb, (Trace_t*)trace->value.dialog);
1352 }
1353
1354 /* Copy settings to local area to allow cancel to work */
1355 val_search_widget_update (trace);
1356
1357 /* manage the popup on the screen */
1358 DManageChild (trace->value.dialog, trace, MC_NOKEYS);
1359 }
1360
val_search_ok_cb(Widget w,Trace_t * trace,XmSelectionBoxCallbackStruct * cb)1361 void val_search_ok_cb (
1362 Widget w,
1363 Trace_t *trace,
1364 XmSelectionBoxCallbackStruct *cb)
1365 {
1366 char *strg;
1367 int i;
1368 char origstrg[MAXVALUELEN];
1369
1370 if (DTPRINT_ENTRY) printf ("In val_search_ok_cb - trace=%p\n",trace);
1371
1372 for (i=0; i<MAX_SRCH; i++) {
1373 ValSearch_t *vs_ptr = &global->val_srch[i];
1374
1375 /* Update with current search enables */
1376 vs_ptr->color = (XmToggleButtonGetState (trace->value.enable[i])) ? i+1 : 0;
1377
1378 /* Update with current cursor enables */
1379 vs_ptr->cursor = (XmToggleButtonGetState (trace->value.cursor[i])) ? i+1 : 0;
1380
1381 /* Update with current search values */
1382 val_to_string (vs_ptr->radix, origstrg, &vs_ptr->value, 0, FALSE, TRUE);
1383 strg = XmTextGetString (trace->value.text[i]);
1384 if (strcmp (origstrg, strg)) {
1385 /* Only update if it has changed, so that a search for a pattern */
1386 /* of X & U's won't disappear when rendered as a simple "X" string */
1387 string_to_value (&vs_ptr->radix, strg, &vs_ptr->value);
1388 }
1389
1390 /* Update with current search values */
1391 strg = XmTextGetString (trace->value.signal[i]);
1392 strcpy (vs_ptr->signal, strg);
1393
1394 if (DTPRINT_SEARCH) {
1395 char strg2[MAXVALUELEN];
1396 val_to_string (global->radixs[0], strg2, &vs_ptr->value, 0, FALSE, TRUE);
1397 printf ("Search %d) %d %s '%s' -> '%s'\n", i, vs_ptr->color,
1398 vs_ptr->radix->name, strg, strg2);
1399 }
1400 }
1401
1402 XtUnmanageChild (trace->value.dialog);
1403
1404 draw_needupd_val_search ();
1405 draw_all_needed ();
1406 }
1407
val_search_apply_cb(Widget w,Trace_t * trace,XmSelectionBoxCallbackStruct * cb)1408 void val_search_apply_cb (
1409 Widget w,
1410 Trace_t *trace,
1411 XmSelectionBoxCallbackStruct *cb)
1412 {
1413 if (DTPRINT_ENTRY) printf ("In val_search_apply_cb - trace=%p\n",trace);
1414
1415 val_search_ok_cb (w,trace,cb);
1416 val_search_cb (trace->main);
1417 }
1418
val_highlight_ev(Widget w,Trace_t * trace,XButtonPressedEvent * ev)1419 void val_highlight_ev (
1420 Widget w,
1421 Trace_t *trace,
1422 XButtonPressedEvent *ev)
1423 {
1424 DTime_t time;
1425 Signal_t *sig_ptr;
1426 Value_t *cptr;
1427
1428 if (DTPRINT_ENTRY) printf ("In val_highlight_ev - trace=%p\n",trace);
1429 if (ev->type != ButtonPress || ev->button!=1) return;
1430
1431 time = posx_to_time (trace, ev->x);
1432 sig_ptr = posy_to_signal (trace, ev->y);
1433 if (!sig_ptr && time<=0) return;
1434 cptr = value_at_time (sig_ptr, time);
1435 if (!cptr) return;
1436
1437 /* Change the color */
1438 if (global->highlight_color > 0) {
1439 ValSearch_t *vs_ptr = &global->val_srch[global->highlight_color - 1];
1440
1441 val_copy (&vs_ptr->value, cptr);
1442 vs_ptr->radix = sig_ptr->radix;
1443 strcpy (vs_ptr->signal, sig_ptr->signame);
1444 if (!vs_ptr->color && !vs_ptr->cursor ) {
1445 /* presume user really wants color if neither is on */
1446 vs_ptr->color = global->highlight_color;
1447 vs_ptr->cursor = global->highlight_color;
1448 }
1449 }
1450
1451 /* If search requester is on the screen, update it too */
1452 if (trace->value.dialog && XtIsManaged (trace->value.dialog)) {
1453 val_search_widget_update (trace);
1454 }
1455
1456 /* redraw the screen */
1457 draw_needupd_val_search ();
1458 draw_all_needed ();
1459 }
1460
1461
1462 /****************************** ANNOTATION ******************************/
1463
val_annotate_cb(Widget w)1464 void val_annotate_cb (
1465 Widget w)
1466 {
1467 Trace_t *trace = widget_to_trace(w);
1468 Widget last;
1469 int i;
1470
1471 if (DTPRINT_ENTRY) printf ("In val_annotate_cb - trace=%p\n",trace);
1472
1473 if (!trace->annotate.dialog) {
1474 XtSetArg (arglist[0], XmNdefaultPosition, TRUE);
1475 XtSetArg (arglist[1], XmNdialogTitle, XmStringCreateSimple ("Annotate Menu"));
1476 XtSetArg (arglist[2], XmNverticalSpacing, 7);
1477 XtSetArg (arglist[3], XmNhorizontalSpacing, 10);
1478 trace->annotate.dialog = XmCreateFormDialog (trace->work, "annotate",arglist,4);
1479
1480 /* create label widget for text widget */
1481 XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple ("File Name") );
1482 XtSetArg (arglist[1], XmNleftAttachment, XmATTACH_FORM );
1483 XtSetArg (arglist[2], XmNtopAttachment, XmATTACH_FORM );
1484 trace->annotate.label1 = XmCreateLabel (trace->annotate.dialog,"l1",arglist,3);
1485 DManageChild (trace->annotate.label1, trace, MC_NOKEYS);
1486
1487 /* create the file name text widget */
1488 XtSetArg (arglist[0], XmNrows, 1);
1489 XtSetArg (arglist[1], XmNcolumns, 30);
1490 XtSetArg (arglist[2], XmNleftAttachment, XmATTACH_FORM );
1491 XtSetArg (arglist[3], XmNrightAttachment, XmATTACH_FORM );
1492 XtSetArg (arglist[4], XmNtopAttachment, XmATTACH_WIDGET );
1493 XtSetArg (arglist[5], XmNtopWidget, dmanage_last );
1494 XtSetArg (arglist[6], XmNresizeHeight, FALSE);
1495 XtSetArg (arglist[7], XmNeditMode, XmSINGLE_LINE_EDIT);
1496 trace->annotate.text = XmCreateText (trace->annotate.dialog,"filename",arglist,8);
1497 DManageChild (trace->annotate.text, trace, MC_NOKEYS);
1498 DAddCallback (trace->annotate.text, XmNactivateCallback, val_annotate_ok_cb, trace);
1499
1500 /* Cursor enables */
1501 XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple ("Include which user (solid) cursor colors:") );
1502 XtSetArg (arglist[1], XmNleftAttachment, XmATTACH_FORM );
1503 XtSetArg (arglist[2], XmNtopAttachment, XmATTACH_WIDGET );
1504 XtSetArg (arglist[3], XmNtopWidget, dmanage_last );
1505 trace->annotate.label2 = XmCreateLabel (trace->annotate.dialog,"l2",arglist,4);
1506 DManageChild (trace->annotate.label2, trace, MC_NOKEYS);
1507
1508 last = trace->annotate.dialog;
1509 for (i=0; i<=MAX_SRCH; i++) {
1510 /* enable button */
1511 XtSetArg (arglist[0], XmNx, 15+30*i);
1512 XtSetArg (arglist[1], XmNtopAttachment, XmATTACH_WIDGET );
1513 XtSetArg (arglist[2], XmNtopWidget, trace->annotate.label2 );
1514 XtSetArg (arglist[3], XmNselectColor, trace->xcolornums[i]);
1515 XtSetArg (arglist[4], XmNlabelString, XmStringCreateSimple (" "));
1516 trace->annotate.cursors[i] = XmCreateToggleButton (trace->annotate.dialog,"togglenc",arglist,5);
1517 DManageChild (trace->annotate.cursors[i], trace, MC_NOKEYS);
1518 last = trace->annotate.cursors[i];
1519 }
1520
1521 /* Cursor enables */
1522 XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple ("Include which auto (dotted) cursor colors:") );
1523 XtSetArg (arglist[1], XmNleftAttachment, XmATTACH_FORM );
1524 XtSetArg (arglist[2], XmNtopAttachment, XmATTACH_WIDGET );
1525 XtSetArg (arglist[3], XmNtopWidget, trace->annotate.cursors[0] );
1526 trace->annotate.label4 = XmCreateLabel (trace->annotate.dialog,"l4",arglist,4);
1527 DManageChild (trace->annotate.label4, trace, MC_NOKEYS);
1528
1529 for (i=0; i<=MAX_SRCH; i++) {
1530 /* enable button */
1531 XtSetArg (arglist[0], XmNx, 15+30*i);
1532 XtSetArg (arglist[1], XmNtopAttachment, XmATTACH_WIDGET );
1533 XtSetArg (arglist[2], XmNtopWidget, trace->annotate.label4 );
1534 XtSetArg (arglist[3], XmNselectColor, trace->xcolornums[i]);
1535 XtSetArg (arglist[4], XmNlabelString, XmStringCreateSimple (" "));
1536 trace->annotate.cursors_dotted[i] = XmCreateToggleButton (trace->annotate.dialog,"togglencd",arglist,5);
1537 DManageChild (trace->annotate.cursors_dotted[i], trace, MC_NOKEYS);
1538 }
1539
1540 /* Signal Enables */
1541 XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple ("Include which signal colors:") );
1542 XtSetArg (arglist[1], XmNleftAttachment, XmATTACH_FORM );
1543 XtSetArg (arglist[2], XmNtopAttachment, XmATTACH_WIDGET );
1544 XtSetArg (arglist[3], XmNtopWidget, trace->annotate.cursors_dotted[0] );
1545 trace->annotate.label3 = XmCreateLabel (trace->annotate.dialog,"",arglist,4);
1546 DManageChild (trace->annotate.label3, trace, MC_NOKEYS);
1547
1548 for (i=1; i<=MAX_SRCH; i++) {
1549 /* enable button */
1550 XtSetArg (arglist[0], XmNx, 15+30*i);
1551 XtSetArg (arglist[1], XmNtopAttachment, XmATTACH_WIDGET );
1552 XtSetArg (arglist[2], XmNtopWidget, trace->annotate.label3 );
1553 XtSetArg (arglist[3], XmNselectColor, trace->xcolornums[i]);
1554 XtSetArg (arglist[4], XmNlabelString, XmStringCreateSimple (" "));
1555 trace->annotate.signals[i] = XmCreateToggleButton (trace->annotate.dialog,"togglen",arglist,5);
1556 DManageChild (trace->annotate.signals[i], trace, MC_NOKEYS);
1557 }
1558
1559 /* Label */
1560 XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple ("Include signals from:") );
1561 XtSetArg (arglist[1], XmNleftAttachment, XmATTACH_FORM );
1562 XtSetArg (arglist[2], XmNtopAttachment, XmATTACH_WIDGET );
1563 XtSetArg (arglist[3], XmNtopWidget, trace->annotate.signals[1]);
1564 trace->annotate.trace_label = XmCreateLabel (trace->annotate.dialog,"",arglist,4);
1565 DManageChild (trace->annotate.trace_label, trace, MC_NOKEYS);
1566
1567 /* Begin pulldown */
1568 trace->annotate.trace_pulldown = XmCreatePulldownMenu (trace->annotate.dialog,"trace_pulldown",arglist,0);
1569
1570 XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple ("All Traces & Deleted") );
1571 trace->annotate.trace_button[TRACESEL_ALLDEL] =
1572 XmCreatePushButtonGadget (trace->annotate.trace_pulldown,"pdbutton2",arglist,1);
1573 DManageChild (trace->annotate.trace_button[TRACESEL_ALLDEL], trace, MC_NOKEYS);
1574
1575 XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple ("All Traces") );
1576 trace->annotate.trace_button[TRACESEL_ALL] =
1577 XmCreatePushButtonGadget (trace->annotate.trace_pulldown,"pdbutton1",arglist,1);
1578 DManageChild (trace->annotate.trace_button[TRACESEL_ALL], trace, MC_NOKEYS);
1579
1580 XtSetArg (arglist[0], XmNlabelString, XmStringCreateSimple ("This Trace") );
1581 trace->annotate.trace_button[TRACESEL_THIS] =
1582 XmCreatePushButtonGadget (trace->annotate.trace_pulldown,"pdbutton0",arglist,1);
1583 DManageChild (trace->annotate.trace_button[TRACESEL_THIS], trace, MC_NOKEYS);
1584
1585 XtSetArg (arglist[0], XmNsubMenuId, trace->annotate.trace_pulldown);
1586 XtSetArg (arglist[1], XmNtopAttachment, XmATTACH_WIDGET );
1587 XtSetArg (arglist[2], XmNtopWidget, trace->annotate.trace_label );
1588 XtSetArg (arglist[3], XmNleftAttachment, XmATTACH_FORM );
1589 trace->annotate.trace_option = XmCreateOptionMenu (trace->annotate.dialog,"options",arglist,4);
1590 DManageChild (trace->annotate.trace_option, trace, MC_NOKEYS);
1591
1592 /* Ok/apply/cancel */
1593 ok_apply_cancel (&trace->annotate.okapply, trace->annotate.dialog,
1594 dmanage_last,
1595 (XtCallbackProc)val_annotate_ok_cb, trace,
1596 (XtCallbackProc)val_annotate_apply_cb, trace,
1597 NULL,NULL,
1598 (XtCallbackProc)unmanage_cb, (Trace_t*)trace->annotate.dialog);
1599 }
1600
1601 /* reset file name */
1602 XtSetArg (arglist[0], XmNvalue, global->anno_filename);
1603 XtSetValues (trace->annotate.text,arglist,1);
1604
1605 /* Menu */
1606 XtSetArg (arglist[0], XmNmenuHistory,
1607 trace->annotate.trace_button[global->anno_traces]);
1608 XtSetValues (trace->annotate.trace_option, arglist, 1);
1609
1610 /* reset enables */
1611 for (i=0; i<=MAX_SRCH; i++) {
1612 XtSetArg (arglist[0], XmNset, (global->anno_ena_cursor[i] != 0));
1613 XtSetValues (trace->annotate.cursors[i], arglist, 1);
1614
1615 XtSetArg (arglist[0], XmNset, (global->anno_ena_cursor_dotted[i] != 0));
1616 XtSetValues (trace->annotate.cursors_dotted[i], arglist, 1);
1617 }
1618 for (i=1; i<=MAX_SRCH; i++) {
1619 XtSetArg (arglist[0], XmNset, (global->anno_ena_signal[i] != 0));
1620 XtSetValues (trace->annotate.signals[i], arglist, 1);
1621 }
1622
1623 /* manage the popup on the screen */
1624 DManageChild (trace->annotate.dialog, trace, MC_NOKEYS);
1625 }
1626
val_annotate_ok_cb(Widget w,Trace_t * trace,XmAnyCallbackStruct * cb)1627 void val_annotate_ok_cb (
1628 Widget w,
1629 Trace_t *trace,
1630 XmAnyCallbackStruct *cb)
1631 {
1632 char *strg;
1633 int i;
1634 Widget clicked;
1635
1636 if (DTPRINT_ENTRY) printf ("In sig_search_ok_cb - trace=%p\n",trace);
1637
1638 /* Update with current search enables */
1639 for (i=0; i<=MAX_SRCH; i++) {
1640 global->anno_ena_cursor[i] = XmToggleButtonGetState (trace->annotate.cursors[i]);
1641 global->anno_ena_cursor_dotted[i] = XmToggleButtonGetState (trace->annotate.cursors_dotted[i]);
1642 }
1643 for (i=1; i<=MAX_SRCH; i++) {
1644 global->anno_ena_signal[i] = XmToggleButtonGetState (trace->annotate.signals[i]);
1645 }
1646
1647 /* Update with current search values */
1648 strg = XmTextGetString (trace->annotate.text);
1649 strcpy (global->anno_filename, strg);
1650
1651 XtSetArg (arglist[0], XmNmenuHistory, &clicked);
1652 XtGetValues (trace->annotate.trace_option, arglist, 1);
1653 for (i=0; i<3; i++) {
1654 if (clicked == trace->annotate.trace_button[i]) {
1655 global->anno_traces = (TraceSel_t)(i);
1656 }
1657 }
1658
1659 global->anno_last_trace = trace;
1660
1661 XtUnmanageChild (trace->annotate.dialog);
1662
1663 val_annotate_do_cb (w,trace,cb);
1664 }
1665
val_annotate_apply_cb(Widget w,Trace_t * trace,XmAnyCallbackStruct * cb)1666 void val_annotate_apply_cb (
1667 Widget w,
1668 Trace_t *trace,
1669 XmAnyCallbackStruct *cb)
1670 {
1671 if (DTPRINT_ENTRY) printf ("In sig_search_apply_cb - trace=%p\n",trace);
1672
1673 val_annotate_ok_cb (w,trace,cb);
1674 val_annotate_cb (trace->main);
1675 }
1676
val_print_quoted(FILE * fp,char * strg)1677 static void val_print_quoted (
1678 FILE *fp,
1679 char *strg)
1680 {
1681 char *cp;
1682 for (cp=strg; *cp; cp++) {
1683 if (*cp == '"') {
1684 fputc ('\\', fp);
1685 }
1686 fputc (*cp, fp);
1687 }
1688 }
1689
val_annotate_do_cb(Widget w,Trace_t * trace,XmAnyCallbackStruct * cb)1690 void val_annotate_do_cb (
1691 Widget w,
1692 Trace_t *trace,
1693 XmAnyCallbackStruct *cb)
1694 {
1695 int i;
1696 Signal_t *sig_ptr;
1697 Trace_t *trace_loop;
1698 Value_t *cptr;
1699 FILE *dump_fp;
1700 DCursor_t *csr_ptr; /* Current cursor being printed */
1701 char strg[1000];
1702 int csr_num, csr_num_incl;
1703
1704 if (DTPRINT_ENTRY) printf ("In val_annotate_cb - trace=%p file=%s\n",trace,global->anno_filename);
1705
1706 draw_update ();
1707
1708 /* Socket connection */
1709 #if HAVE_SOCKETS
1710 socket_create ();
1711 #endif
1712
1713 if (global->anno_last_trace == NULL) global->anno_last_trace = global->trace_head;
1714
1715 if (! (dump_fp=fopen (global->anno_filename, "w"))) {
1716 sprintf (message,"Bad Filename: %s\n", global->anno_filename);
1717 dino_error_ack (trace,message);
1718 return;
1719 }
1720
1721 fprintf (dump_fp, "(setq dinotrace-program-version \"%s\")\n\n", DTVERSION);
1722
1723 /* Socket info */
1724 if (!global->anno_socket[0] || strchr (global->anno_socket, '*') ) {
1725 fprintf (dump_fp, "(setq dinotrace-socket-name nil)\n");
1726 }
1727 else {
1728 fprintf (dump_fp, "(setq dinotrace-socket-name \"%s\")\n\n",
1729 global->anno_socket);
1730 }
1731
1732 fprintf (dump_fp, "(setq dinotrace-hierarchy-separator \"%c\")\n\n",
1733 global->trace_head->dfile.hierarchy_separator);
1734
1735 /* Trace info */
1736 fprintf (dump_fp, "(setq dinotrace-traces '(\n");
1737 for (trace = global->trace_head; trace; trace = trace->next_trace) {
1738 if (trace->loaded) {
1739 fprintf (dump_fp, " [\"%s\"\t\"%s\"]\n",
1740 trace->dfile.filename,
1741 date_string (trace->dfile.filestat.st_ctime));
1742 }
1743 }
1744 fprintf (dump_fp, "\t))\n");
1745
1746 #define colornum_to_name(_color_) (((_color_)==0)?"":global->color_names[(_color_)])
1747 /* Cursor info */
1748 /* [time color-num color-name nil(font) note] */
1749 fprintf (dump_fp, "(setq dinotrace-cursors [\n");
1750 for (csr_ptr = global->cursor_head; csr_ptr; csr_ptr = csr_ptr->next) {
1751 if ((csr_ptr->type==USER) ? global->anno_ena_cursor[csr_ptr->color] : global->anno_ena_cursor_dotted[csr_ptr->color] ) {
1752 time_to_string (global->trace_head, strg, csr_ptr->time, FALSE);
1753 fprintf (dump_fp, "\t[\"%s\"\t%d\t\"%s\"\tnil\t", strg,
1754 csr_ptr->color, colornum_to_name(csr_ptr->color));
1755 if (csr_ptr->note) fprintf (dump_fp, "\"%s\"", csr_ptr->note);
1756 else fprintf (dump_fp, "nil");
1757 fprintf (dump_fp, "]\n");
1758 }
1759 }
1760 fprintf (dump_fp, "\t])\n");
1761
1762 /* Value search info */
1763 /* [value color-num color-name] */
1764 fprintf (dump_fp, "(setq dinotrace-value-searches '(\n");
1765 for (i=1; i<=MAX_SRCH; i++) {
1766 ValSearch_t *vs_ptr = &global->val_srch[i-1];
1767 if (vs_ptr->color) {
1768 val_to_string (vs_ptr->radix, strg, &vs_ptr->value, 0, FALSE, FALSE);
1769 fprintf (dump_fp, "\t[\"");
1770 val_print_quoted (dump_fp, strg);
1771 fprintf (dump_fp, "\"\t%d\t\"%s\"]\n", i, colornum_to_name(i));
1772 }
1773 }
1774 fprintf (dump_fp, "\t))\n");
1775
1776 /* Signal color info */
1777 /* 0's never actually used, but needed in the array so aref will work in emacs */
1778 /* [color-num color-name] */
1779 fprintf (dump_fp, "(setq dinotrace-signal-colors [\n");
1780 for (i=0; i<=MAX_SRCH; i++) {
1781 fprintf (dump_fp, "\t[%d\t\"%s\"\tnil]\n", i, (i==0 || !global->color_names[i])?"":global->color_names[i]);
1782 }
1783 fprintf (dump_fp, "\t])\n");
1784
1785 /* Find number of cursors that will be included */
1786 csr_num_incl = 0;
1787 for (csr_ptr = global->cursor_head; csr_ptr; csr_ptr = csr_ptr->next) {
1788 if ((csr_ptr->type==USER) ? global->anno_ena_cursor[csr_ptr->color] : global->anno_ena_cursor_dotted[csr_ptr->color] ) {
1789 csr_num_incl++;
1790 }
1791 }
1792
1793 /* Signal values */
1794 /* (basename [name color-num note values] nil(propertied)) */
1795 fprintf (dump_fp, "(setq dinotrace-signal-values '(\n");
1796 for (trace_loop = global->deleted_trace_head; trace_loop; trace_loop = trace_loop->next_trace) {
1797 /* Process the deleted trace last, so visible values override deleted values */
1798 trace = trace_loop->next_trace ? trace_loop->next_trace : global->deleted_trace_head;
1799 if (( global->anno_traces == TRACESEL_THIS && trace!=global->anno_last_trace)
1800 || (global->anno_traces == TRACESEL_ALL && trace==global->deleted_trace_head)) {
1801 continue;
1802 }
1803
1804 for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_ptr->forward) {
1805 char *basename, *p;
1806 basename = strdup (sig_basename (trace, sig_ptr));
1807 p = strrchr (basename, '['); /* Not vector_separator: it's standardized by here*/
1808 if (p) *p = '\0';
1809 fprintf (dump_fp, "\t(\"%s\"\t", basename);
1810
1811 fprintf (dump_fp, "\t[\"%s\"\t", sig_ptr->signame);
1812 if (global->anno_ena_signal[sig_ptr->color]) fprintf (dump_fp, "%d\t", sig_ptr->color);
1813 else fprintf (dump_fp, "nil\t");
1814
1815 if (sig_ptr->note) fprintf (dump_fp, "\"%s\"\t", sig_ptr->note);
1816 else fprintf (dump_fp, "nil\t");
1817
1818 fprintf (dump_fp, "(");
1819 csr_num=0;
1820 cptr = sig_ptr->cptr;
1821 for (csr_ptr = global->cursor_head; csr_ptr; csr_ptr = csr_ptr->next) {
1822
1823 if ((csr_ptr->type==USER) ? global->anno_ena_cursor[csr_ptr->color] : global->anno_ena_cursor_dotted[csr_ptr->color] ) {
1824 csr_num++;
1825
1826 /* Note grabs value to right of cursor */
1827 while ( (CPTR_TIME(cptr) < csr_ptr->time)
1828 && (CPTR_TIME(cptr) != EOT)) {
1829 cptr = CPTR_NEXT(cptr);
1830 }
1831 if ( (CPTR_TIME(cptr) > csr_ptr->time)
1832 && ( cptr > sig_ptr->bptr)) {
1833 cptr = CPTR_PREV(cptr);
1834 }
1835
1836 val_to_string (sig_ptr->radix, strg, cptr, sig_ptr->bits, FALSE, FALSE);
1837
1838 /* First value must have `, last must have ', commas in middle */
1839 fprintf (dump_fp, "\"");
1840 if (csr_num==1) fprintf (dump_fp, "`");
1841 else fprintf (dump_fp, ",");
1842 val_print_quoted (dump_fp, strg);
1843 if (csr_num==csr_num_incl) fprintf (dump_fp, "'");
1844 fprintf (dump_fp, "\"\t");
1845 }
1846 }
1847 fprintf (dump_fp, ") nil])\n");
1848 free(basename);
1849 }
1850 }
1851 fprintf (dump_fp, "\t))\n");
1852
1853 fclose (dump_fp);
1854 }
1855
1856