1 /******************************************************************************
2 * DESCRIPTION: Dinotrace source: configuration 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 # Undocumented:
57 # debug ON | OFF
58 # print <number> | ON | OFF
59 #
60 # # Comment
61 # Config:
62 # click_to_edge ON | OFF
63 # cursor ON | OFF
64 # refreshing AUTO | MANUAL
65 # grid <grid_number> ON | OFF
66 # grid_align <grid_number> <number> | ASSERTION | DEASSERTION
67 # grid_resolution <grid_number> <number> | AUTO | EDGE
68 # grid_type <grid_number> NORMAL | WIDE
69 # grid_signal <grid_number> <signal_pattern>
70 # grid_color <grid_number> <color>
71 # page_inc 4 | 2 | 1
72 # print_size A | B | EPSPORT | EPSLAND
73 # rise_fall_time <number>
74 # signal_height <number>
75 # time_format %0.6lf | %0.6lg | ""
76 # time_precision US | NS | PS | FS
77 # time_rep <number> | US | NS | PS | FS | CYCLE
78 # File Format:
79 # file_format DECSIM | TEMPEST | VERILOG
80 # save_enables ON | OFF
81 # save_ordering ON | OFF
82 # save_duplicates ON | OFF
83 # signal_states <signal_pattern> = {<State>, <State>...}
84 # vector_separator "<char>"
85 # hierarchy_separator "<chars>"
86 # time_multiplier <number>
87 # Geometry/resources:
88 # open_geometry <width>[%]x<height>[%]+<xoffset>[%]+<yoff>[%]
89 # shrink_geometry <width>%x<height>%+<xoffset>%+<yoff>%
90 # start_geometry <width>x<height>+<xoffset>+<yoffset>
91 # Modification of traces:
92 # signal_delete <signal_pattern>
93 # signal_delete_constant <signal_pattern> [-IGNOREXZ]
94 # signal_add <signal_pattern> [<after_signal_first_matches>] [<color>]
95 # signal_copy <signal_pattern> [<after_signal_first_matches>] [<color>]
96 # signal_move <signal_pattern> [<after_signal_first_matches>] [<color>]
97 # signal_radix <signal_pattern> <HEX|BINARY|OCT|ASCII|DEC>
98 # signal_waveform <signal_pattern> <DIGITAL|ANALOG|ANALOG_SIGNED>
99 # signal_rename <signal_pattern> <new_signal_name> [<color>]
100 # signal_highlight <signal_pattern> <color>
101 # signal_note <signal_pattern> <note>
102 # cursor_add <time> <color> [-USER]
103 # value_highlight <value> <color> [<signal_pattern>] [-CURSOR] [-VALUE]
104 # Display changes:
105 # signal_goto <signal_pattern> (if not on screen, first match)
106 # time_goto <time>
107 # resolution <res>
108 # refresh
109 # annotate
110 *****************************************************************************/
111
112
113 #include "dinotrace.h"
114
115 #include "functions.h"
116
117 /**********************************************************************/
118
119 /* See the ascii map to have this make sense */
120 #define issigchr(ch) ( ((ch)>' ') && ((ch)!='=') && ((ch)!='\"') && ((ch)!='\'') )
121
122 #define isstatechr(ch) ( ((ch)>' ') && ((ch)!=',') && ((ch)!='=') && ((ch)!='{') && ((ch)!='}') && ((ch)!='\"') && ((ch)!='\'') )
123
124 #define isstatesep(ch) (!isstatechr(ch) && (ch)!='}' )
125
126
127 /* File locals */
128 static Boolean_t config_report_errors;
129 static char *config_file="";
130 static int config_line_num=0;
131 static Boolean_t config_reading_socket;
132
133 /**********************************************************************
134 * Utils
135 */
136
config_error_ack(Trace_t * trace,char * message)137 void config_error_ack (
138 Trace_t *trace,
139 char *message)
140 {
141 char newmessage[1000];
142
143 if (!config_report_errors) return;
144
145 strcpy (newmessage, message);
146 if (config_reading_socket) {
147 sprintf (newmessage + strlen(newmessage), "on command # %d from socket %s\n", config_line_num, config_file);
148 }
149 else {
150 sprintf (newmessage + strlen(newmessage), "on line %d of %s\n", config_line_num, config_file);
151 }
152 dino_error_ack (trace, newmessage);
153 }
154
155 /**********************************************************************
156 * READING FUNCTIONS
157 **********************************************************************/
158
config_get_line(char * line,int len,FILE * readfp)159 static void config_get_line (
160 char *line,
161 int len,
162 FILE *readfp)
163 {
164 char *tp;
165
166 /* Read line & kill EOL at end */
167 fgets (line, len, readfp);
168 if (*line && *(tp=(line+strlen(line)-1))=='\n') *tp='\0';
169 config_line_num++;
170 }
171
config_read_string(Trace_t * trace,char * line,char * out)172 static int config_read_string (
173 Trace_t *trace,
174 char *line,
175 char *out)
176 {
177 int outlen=0;
178 Boolean_t quote = FALSE;
179
180 while (*line && isspace(*line)) {
181 line++; outlen++;
182 }
183
184 if (*line=='"') {
185 line++; outlen++;
186 quote = TRUE;
187 }
188
189 while (*line && (quote ? *line!='"' : issigchr(*line))) {
190 if (*line == '\\') {
191 line++;
192 outlen++;
193 switch (*line) {
194 case '\0':
195 line--;
196 break;
197 case 'n':
198 *out++ = '\n';
199 break;
200 default:
201 *out++ = *line;
202 }
203 }
204 else {
205 *out++ = *line;
206 }
207 line++; outlen++;
208 }
209
210 if (quote) {
211 if (*line == '"') {
212 line++; outlen++;
213 } else {
214 config_error_ack (trace, "Double quotes aren't terminated\n");
215 }
216 }
217 *out++ = '\0';
218 return (outlen);
219 }
220
config_read_value(Trace_t * trace,char * line,char * out)221 static int config_read_value (
222 Trace_t *trace,
223 char *line,
224 char *out)
225 {
226 int outlen=0;
227 Boolean_t quote = FALSE;
228
229 while (*line && isspace(*line)) {
230 line++; outlen++;
231 }
232
233 if (*line=='"') {
234 *out++ = *line;
235 line++; outlen++;
236 quote = TRUE;
237 }
238
239 while (*line && (quote ? *line!='"' : !isspace(*line))) {
240 if (*line == '\\') {
241 line++;
242 outlen++;
243 switch (*line) {
244 case '\0':
245 line--;
246 break;
247 case 'n':
248 *out++ = '\n';
249 break;
250 default:
251 *out++ = *line;
252 }
253 }
254 else {
255 *out++ = *line;
256 }
257 line++; outlen++;
258 }
259
260 if (quote) {
261 if (*line == '"') {
262 *out++ = *line;
263 line++; outlen++;
264 } else {
265 config_error_ack (trace, "Double quotes aren't terminated\n");
266 }
267 }
268 *out++ = '\0';
269 return (outlen);
270 }
271
config_read_pattern(Trace_t * trace,char * line,char * pattern)272 static int config_read_pattern (
273 Trace_t *trace,
274 char *line,
275 char *pattern)
276 {
277 int outlen;
278 outlen = config_read_string (trace, line, pattern);
279 if (!pattern[0]) {
280 config_error_ack (trace, "Signal pattern name must not be null\n");
281 }
282 return (outlen);
283 }
284
config_read_state(char * line,char * out,int * statenum_ptr)285 static int config_read_state (
286 char *line,
287 char *out,
288 int *statenum_ptr)
289 {
290 char *tp;
291 int outlen=0;
292
293 while (*line && isstatesep(*line)) {
294 line++;
295 outlen++;
296 }
297
298 if (!*line) {
299 out[0]='\0';
300 return(outlen);
301 }
302
303 for (tp=line; *tp && isdigit(*tp); tp++) ;
304 if (*tp++ == '=') {
305 /* 22=statename type assignment */
306 *statenum_ptr = atoi (line);
307 outlen += (tp - line);
308 line = tp;
309 }
310
311 /* extract state */
312 strncpy(out, line, MAXVALUELEN);
313 out[MAXVALUELEN-1]='\0';
314 for (tp=out; *tp && isstatechr(*tp); tp++) ;
315 *tp='\0';
316
317 return (strlen(out)+outlen);
318 }
319
config_read_int(char * line,int * out)320 static int config_read_int (
321 char *line,
322 int *out)
323 {
324 int outlen=0;
325
326 while (*line && !isalnum(*line) && *line!='-') {
327 line++;
328 outlen++;
329 }
330
331 if (!*line) {
332 *out=0;
333 return(outlen);
334 }
335
336 /* extract command */
337 *out = atoi(line);
338 while (*line && isdigit(*line)) {
339 line++;
340 outlen++;
341 }
342
343 return (outlen);
344 }
345
346
347 /**********************************************************************
348 * SUPPORT FUNCTIONS
349 **********************************************************************/
350
signalstate_find(const Trace_t * trace,const char * name)351 SignalState_t *signalstate_find (
352 const Trace_t *trace,
353 const char *name)
354 {
355 register SignalState_t *sig;
356
357 for (sig=global->signalstate_head; sig; sig=sig->next) {
358 /* printf ("'%s'\t'%s'\n", name, sig->signame); */
359 if (wildmat(name, sig->signame))
360 return (sig);
361 }
362 return (NULL);
363 }
364
signalstate_add(Trace_t * trace,SignalState_t * info)365 static void signalstate_add (
366 Trace_t *trace,
367 SignalState_t *info)
368 {
369 SignalState_t *newp;
370 int t;
371
372 for (newp = global->signalstate_head; newp ; newp=newp->next) {
373 if (!strcmp (newp->signame, info->signame)) break;
374 }
375 if (! newp) {
376 /* Not found, add & relink */
377 newp = XtNew (SignalState_t);
378 memcpy ((void *)newp, (void *)info, sizeof(SignalState_t));
379 newp->next = global->signalstate_head;
380 global->signalstate_head = newp;
381 draw_needupd_val_states ();
382 }
383 else {
384 /* Found, overwrite old */
385 info->next = newp->next; /* Don't loose the link */
386 memcpy ((void *)newp, (void *)info, sizeof(SignalState_t));
387 }
388
389 /*printf ("Signal '%s' Assigned States:\n", newp->signame);*/
390 for (t=0; t<MAXSTATENAMES; t++) {
391 if (newp->statename[t][0] != '\0') {
392 newp->numstates = t+1;
393 /*printf ("State %d = '%s'\n", t, newp->statename[t]);*/
394 }
395 }
396 }
397
signalstate_free(void)398 static void signalstate_free (void)
399 {
400 SignalState_t *sstate_ptr, *last_ptr;
401
402 sstate_ptr = global->signalstate_head;
403 while (sstate_ptr) {
404 last_ptr = sstate_ptr->next;
405 DFree (sstate_ptr);
406 sstate_ptr = last_ptr;
407 }
408 global->signalstate_head = NULL;
409 }
410
signalstate_write(FILE * writefp,const char * c)411 static void signalstate_write (
412 FILE *writefp, const char *c)
413 {
414 SignalState_t *sstate_ptr;
415 int i;
416
417 fprintf (writefp, "\n#### Global Signal States ####\n");
418
419 for (sstate_ptr = global->signalstate_head;
420 sstate_ptr; sstate_ptr = sstate_ptr->next) {
421 fprintf (writefp, "%ssignal_states %s {\n",c,sstate_ptr->signame);
422 for (i=0; i<MAXSTATENAMES; i++) {
423 if (sstate_ptr->statename[i][0]) {
424 fprintf (writefp, "%s\t%d=\"%s\",\n",c, i, sstate_ptr->statename[i]);
425 }
426 }
427 fprintf (writefp, "%s\t}\n",c);
428 }
429 fprintf (writefp,"\n");
430 }
431
config_parse_geometry(char * line,Geometry_t * geometry)432 void config_parse_geometry (
433 char *line,
434 Geometry_t *geometry)
435 /* Like XParseGeometry, but handles percentages */
436 {
437 int flags;
438 int x,y;
439 uint_t wid, hei;
440 char noper_line[100];
441 char *tp;
442
443 /* Copy line into a temp, remove the percentage symbols, and parse it */
444 strcpy (noper_line, line);
445 while ((tp=strchr (noper_line, '%'))) strcpy_overlap (tp, tp+1);
446
447 flags = XParseGeometry (noper_line, &x, &y, &wid, &hei);
448 if (flags & WidthValue) geometry->width = wid;
449 if (flags & HeightValue) geometry->height = hei;
450 if (flags & XValue) geometry->x = x;
451 if (flags & YValue) geometry->y = y;
452
453 /* Now figure out what the percentage symbols apply to */
454 geometry->xp = geometry->yp = geometry->heightp = geometry->widthp = FALSE;
455 for (tp = line; *tp; ) {
456 while (*tp && !isdigit(*tp)) tp++;
457 while (isdigit(*tp)) tp++;
458 if (*tp=='%') {
459 if (flags & WidthValue) geometry->widthp = TRUE;
460 else if (flags & HeightValue) geometry->heightp = TRUE;
461 else if (flags & XValue) geometry->xp = TRUE;
462 else if (flags & YValue) geometry->yp = TRUE;
463 }
464 if (flags & WidthValue) flags &= flags & (~ WidthValue);
465 else if (flags & HeightValue) flags &= flags & (~ HeightValue);
466 else if (flags & XValue) flags &= flags & (~ XValue);
467 else if (flags & YValue) flags &= flags & (~ YValue);
468 }
469
470 if (DTPRINT_CONFIG) printf ("geometry %s = %dx%d+%d+%d %c%c%c%c\n", line,
471 geometry->width, geometry->height,
472 geometry->x, geometry->y,
473 geometry->widthp?'%':'-', geometry->heightp?'%':'-',
474 geometry->xp?'%':'-', geometry->yp?'%':'-');
475 }
476
config_geometry_string(Geometry_t * geometry,char * strg)477 static void config_geometry_string (
478 Geometry_t *geometry,
479 char *strg)
480 {
481 sprintf (strg, "%d%sx%d%s+%d%s+%d%s",
482 geometry->width, geometry->widthp?"%":"",
483 geometry->height, geometry->heightp?"%":"",
484 geometry->x, geometry->xp?"%":"",
485 geometry->y, geometry->xp?"%":"");
486 }
487
488
489 /**********************************************************************
490 * reading functions w/ error messages
491 **********************************************************************/
492
config_read_on_off(Trace_t * trace,char * line,int * out)493 static int config_read_on_off (
494 Trace_t *trace,
495 char *line,
496 int *out)
497 /* Read boolean flag line, return <= 0 and print msg if bad */
498 {
499 char cmd[MAXSIGLEN];
500 int outlen;
501
502 outlen = config_read_string (trace, line, cmd);
503
504 if (!strcasecmp (cmd, "ON") || !strcmp (cmd, "1"))
505 *out = 1;
506 else if (!strcasecmp (cmd, "OFF") || !strcmp (cmd, "0"))
507 *out = 0;
508 else {
509 sprintf (message, "Expected ON or OFF switch\n");
510 config_error_ack (trace, message);
511 *out = -1;
512 }
513
514 return (outlen);
515 }
516
config_read_color(Trace_t * trace,char * line,ColorNum_t * color,Boolean_t warn)517 static int config_read_color (
518 Trace_t *trace,
519 char *line,
520 ColorNum_t *color,
521 Boolean_t warn)
522 /* Read color name from line, return <= 0 and print msg if bad */
523 {
524 int outlen=0;
525 char cmd[MAXSIGLEN];
526
527 while (*line && isspace(*line)) {
528 line++; outlen++;
529 }
530
531 switch (*line) {
532 case 'N': case 'n':
533 outlen += config_read_string (trace, line, cmd);
534 *color = global->highlight_color;
535 break;
536 case 'C': case 'c':
537 /* Duplicate code in submenu_to_color */
538 outlen += config_read_string (trace, line, cmd);
539 if ((++global->highlight_color) > MAX_SRCH) global->highlight_color = 1;
540 *color = global->highlight_color;
541 break;
542 case '0': case '1': case '2':case '3':case '4':
543 case '5': case '6': case '7':case '8':case '9':
544 outlen += config_read_int (line, color);
545 if (*color < 0 || *color > MAX_SRCH) {
546 if (warn) {
547 sprintf (message, "Color numbers must be 0 to %d, NEXT or CURRENT\n", MAX_SRCH);
548 config_error_ack (trace, message);
549 }
550 *color = -1;
551 }
552 break;
553 default:
554 *color = -1;
555 break;
556 }
557
558 return (outlen);
559 }
560
config_read_grid(Trace_t * trace,char * line,Grid_t ** grid_pptr)561 int config_read_grid (
562 Trace_t *trace,
563 char *line,
564 Grid_t **grid_pptr)
565 /* Read grid number name from line, return < 0 and print msg if bad */
566 {
567 int outlen;
568 int grid_num;
569 char message [100];
570
571 outlen = config_read_int (line, &grid_num);
572
573 if (grid_num < 0 || grid_num > MAXGRIDS) {
574 sprintf (message, "Grid numbers must be 0 to %d\n", MAXGRIDS);
575 grid_num = -1;
576 *grid_pptr = NULL;
577 }
578 else {
579 *grid_pptr = &(trace->grid[grid_num]);
580 }
581
582 return (outlen);
583 }
584
585 /**********************************************************************
586 * config_process_states
587 **********************************************************************/
588
config_process_state(Trace_t * trace,char * line,SignalState_t * sstate_ptr)589 static int config_process_state (
590 Trace_t *trace,
591 char *line,
592 SignalState_t *sstate_ptr)
593 {
594 char newstate[MAXVALUELEN];
595 int statenum = sstate_ptr->numstates;
596 int outlen=0;
597
598 if (*line && *line!='}') {
599 outlen = config_read_state (line, newstate, &statenum);
600 line += outlen;
601 /*printf ("Got = %d '%s'\n", statenum, newstate);*/
602 if (statenum < 0 || statenum >= MAXSTATENAMES) {
603 sprintf (message, "Over maximum of %d SIGNAL_STATES for signal %s\n",
604 MAXSTATENAMES, sstate_ptr->signame);
605 config_error_ack (trace,message);
606 /* No return, as will just ignore remaining errors */
607 }
608 else {
609 if (newstate[0]) {
610 sstate_ptr->numstates = statenum+1;
611 strcpy (sstate_ptr->statename[statenum], newstate);
612 }
613 }
614 }
615 return (outlen);
616 }
617
618
619 /**********************************************************************
620 * config_process_line
621 **********************************************************************/
622
config_process_line_internal(Trace_t * trace,char * line,Boolean_t format_only,Boolean_t eof)623 static void config_process_line_internal (
624 Trace_t *trace,
625 char *line,
626 Boolean_t format_only,
627 Boolean_t eof) /* Final call of process_line with EOF */
628 {
629 char cmd[MAXSIGLEN];
630 int value;
631 Grid_t *grid_ptr;
632 char pattern[MAXSIGLEN];
633 char *cmt;
634
635 static SignalState_t newsigst;
636 static Boolean_t processing_sig_state = FALSE;
637
638 re_process_line:
639
640 /* Strip spaces and comments */
641 while (*line && isspace(*line)) line++;
642 cmt = line;
643 while (cmt != NULL) {
644 cmt=strpbrk(cmt,"!#\"");
645 if (cmt!=NULL) {
646 if (*cmt=='\"') {
647 cmt=strpbrk(cmt+1,"\""); /* Skip to closing quote */
648 continue;
649 }
650 *cmt = '\0';
651 break;
652 }
653 }
654 if ((line[0]==';') || (line[0]=='\0')) return;
655
656 /* if (DTPRINT_CONFIG) printf ("Cmd='%s'\n",cmd); */
657
658 if (processing_sig_state) {
659 if (*line == ';' || *line=='}' || eof) {
660 if (eof) {
661 config_error_ack (trace, "Unexpected EOF during SIGNAL_STATES\n");
662 }
663 signalstate_add (trace, &newsigst);
664 processing_sig_state = FALSE;
665 }
666 else {
667 line += config_process_state (trace, line, &newsigst);
668 goto re_process_line;
669 }
670 }
671 else {
672 /* General commands */
673
674 /* Preprocessor #INCLUDE eventually */
675 /* extract command */
676 line += config_read_string (trace, line, cmd);
677 while (*line && isspace(*line)) line++;
678 upcase_string (cmd);
679
680 if (!strcmp(cmd, "DEBUG")) {
681 value=DTDEBUG;
682 line += config_read_on_off (trace, line, &value);
683 if (value >= 0) {
684 if (DTPRINT) printf ("Config: DTDEBUG=%d\n",value);
685 DTDEBUG=value;
686 }
687 }
688 else if (!strcmp(cmd, "PRINT")) {
689 value=DTPRINT;
690 if (toupper(line[0])=='O' && toupper(line[1])=='N') DTPRINT = ~0;
691 else if (toupper(line[0])=='O' && toupper(line[1])=='F') DTPRINT = 0;
692 else {
693 sscanf (line, "%x", &value);
694 if (value > 0) {
695 DTPRINT=value;
696 }
697 else {
698 config_error_ack (trace, "Print must be set ON, OFF, or > 0\n");
699 }
700 }
701 if (DTPRINT) printf ("Config: DTPRINT=0x%x\n",value);
702 }
703 /************************************************************/
704 /* Commands needed before a file is read */
705 /* These should be only global or dfile parameters (not trace parameters) */
706 else if (!strcmp(cmd, "FILE_FORMAT")) {
707 char *tp;
708 for (tp = line; *tp && *tp!='Z' && *tp!='z'; tp++) ;
709 switch (toupper(line[0])) {
710 case 'D':
711 file_format = FF_DECSIM;
712 break;
713 case 'T':
714 file_format = FF_TEMPEST;
715 break;
716 case 'V':
717 if (toupper(line[1]) == 'P') {
718 file_format = FF_VERILOG_VPD;
719 } else {
720 file_format = FF_VERILOG;
721 }
722 break;
723 default:
724 config_error_ack (trace, "File_Format must be DECSIM, TEMPEST, VPD or VERILOG\n");
725 }
726 if (DTPRINT_CONFIG) printf ("File_format = %d\n", file_format);
727 }
728 else if (!strcmp(cmd, "SAVE_ENABLES")) {
729 value=global->save_enables;
730 line += config_read_on_off (trace, line, &value);
731 if (value >= 0) {
732 global->save_enables=value;
733 }
734 }
735 else if (!strcmp(cmd, "SAVE_ORDERING")) {
736 value=global->save_ordering;
737 line += config_read_on_off (trace, line, &value);
738 if (value >= 0) {
739 global->save_ordering=value;
740 }
741 }
742 else if (!strcmp(cmd, "SAVE_DUPLICATES")) {
743 value=global->save_duplicates;
744 line += config_read_on_off (trace, line, &value);
745 if (value >= 0) {
746 global->save_duplicates=value;
747 }
748 }
749 else if (!strcmp(cmd, "TIME_REP")) {
750 switch (toupper(line[0])) {
751 case 'N': global->timerep = TIMEREP_NS; break;
752 case 'U': global->timerep = TIMEREP_US; break;
753 case 'P': global->timerep = TIMEREP_PS; break;
754 case 'F': global->timerep = TIMEREP_FS; break;
755 case 'C': global->timerep = TIMEREP_CYC; break;
756 case '0': case '1': case '2': case '3': case '4':
757 case '5': case '6': case '7': case '8': case '9': case '.':
758 global->timerep = atof(line); break;
759 default:
760 config_error_ack (trace, "Time_Rep must be FS, PS, NS, US, or CYCLE\n");
761 }
762 if (DTPRINT_CONFIG) printf ("timerep = %f\n", global->timerep);
763 }
764 else if (!strcmp(cmd, "TIME_PRECISION")) {
765 switch (toupper(line[0])) {
766 case 'N': global->time_precision = TIMEREP_NS; break;
767 case 'U': global->time_precision = TIMEREP_US; break;
768 case 'P': global->time_precision = TIMEREP_PS; break;
769 case 'F': global->time_precision = TIMEREP_FS; break;
770 default:
771 config_error_ack (trace, "Time_Precision must be FS, PS, NS, or US\n");
772 }
773 if (DTPRINT_CONFIG) printf ("time_precision = %f\n", global->time_precision);
774 }
775 else if (!strcmp(cmd, "TIME_FORMAT")) {
776 line += config_read_string (trace, line, cmd);
777 strcpy (global->time_format, cmd);
778 if (DTPRINT_CONFIG) printf ("time_format = '%s'\n", global->time_format);
779 }
780 else if (!strcmp(cmd, "TIME_MULTIPLIER")) {
781 value = global->tempest_time_mult;
782 line += config_read_int (line, &value);
783 if (value > 0) global->tempest_time_mult = value;
784 else {
785 config_error_ack (trace, "Time_Mult must be > 0\n");
786 }
787 }
788 else if (!strcmp(cmd, "HIERARCHY_SEPARATOR")) {
789 line += config_read_string (trace, line, pattern);
790 if (pattern[0]) {
791 trace->dfile.hierarchy_separator = pattern[0];
792 }
793 }
794 else if (!strcmp(cmd, "VECTOR_SEPERATOR") /* Backward compatible spelling! */
795 || !strcmp(cmd, "VECTOR_SEPARATOR")) {
796 if (*line=='"') line++;
797 if (*line && *line!='"') {
798 trace->dfile.vector_separator = line[0];
799 }
800 else {
801 trace->dfile.vector_separator = '\0';
802 }
803 /* Take a stab at the ending character */
804 switch (trace->dfile.vector_separator) {
805 case '`': trace->dfile.vectorend_separator = '\''; break;
806 case '(': trace->dfile.vectorend_separator = ')'; break;
807 case '[': trace->dfile.vectorend_separator = ']'; break;
808 case '{': trace->dfile.vectorend_separator = '}'; break;
809 case '<': trace->dfile.vectorend_separator = '>'; break;
810 default: trace->dfile.vectorend_separator = trace->dfile.vector_separator; break; /* a wild guess SIG$20:1$? */
811 }
812 if (DTPRINT_CONFIG) printf ("vector_separator = '%c' End='%c'\n",
813 trace->dfile.vector_separator, trace->dfile.vectorend_separator);
814 }
815 else if (format_only) {
816 return;
817 }
818 /**************************************************************/
819 /** beginning of non-file_format commands */
820 /**************************************************************/
821 else if (!strcmp(cmd, "CURSOR")) {
822 value = global->cursor_vis;
823 line += config_read_on_off (trace, line, &value);
824 if (value >= 0) {
825 if (DTPRINT_CONFIG) printf ("Config: cursor_vis=%d\n",value);
826 global->cursor_vis = value;
827 }
828 }
829 else if (!strcmp(cmd, "CLICK_TO_EDGE")) {
830 value = global->click_to_edge;
831 line += config_read_on_off (trace, line, &value);
832 if (value >= 0) {
833 if (DTPRINT_CONFIG) printf ("Config: click_to_edge=%d\n",value);
834 global->click_to_edge = value;
835 }
836 }
837 else if (!strcmp(cmd, "DRAW_PREFIX")) {
838 value = global->prefix_enable;
839 line += config_read_on_off (trace, line, &value);
840 if (value >= 0) {
841 global->prefix_enable = value;
842 }
843 }
844 else if (!strcmp(cmd, "REFRESHING")) {
845 if (toupper(line[0])=='A')
846 global->redraw_manually = FALSE;
847 else if (toupper(line[0])=='M')
848 global->redraw_manually = TRUE;
849 else {
850 config_error_ack (trace, "Refreshing must be AUTO, or MANUAL\n");
851 }
852 }
853 else if (!strcmp(cmd, "SIGNAL_HEIGHT")) {
854 value = global->sighgt;
855 line += config_read_int (line, &value);
856 if (value >= 10 && value <= 50)
857 global->sighgt = value;
858 else {
859 config_error_ack (trace, "Signal_height must be 10-50\n");
860 }
861 }
862 else if (!strcmp(cmd, "GRID")) {
863 line += config_read_grid (trace, line, &grid_ptr);
864 line += config_read_on_off (trace, line, &value);
865 if (grid_ptr && value >= 0) {
866 if (DTPRINT_CONFIG) printf ("Config: grid_vis=%d\n",value);
867 grid_ptr->visible = value;
868 }
869 }
870 else if (!strcmp(cmd, "GRID_RESOLUTION")) {
871 line += config_read_grid (trace, line, &grid_ptr);
872 line += config_read_string (trace, line, pattern);
873 if (grid_ptr) {
874 if (isalpha(pattern[0])) {
875 if (toupper(pattern[0])=='A')
876 grid_ptr->period_auto = PA_AUTO;
877 else if (toupper(pattern[0])=='E')
878 grid_ptr->period_auto = PA_EDGE;
879 else {
880 config_error_ack (trace, "Grid_res must be >0, AUTO or EDGE\n");
881 }
882 }
883 else {
884 value = string_to_time (trace, pattern);
885 grid_ptr->period = value;
886 grid_ptr->period_auto = PA_USER;
887 }
888 }
889 }
890 else if (!strcmp(cmd, "GRID_ALIGN")) {
891 line += config_read_grid (trace, line, &grid_ptr);
892 line += config_read_string (trace, line, pattern);
893 if (isalpha(pattern[0])) {
894 if (toupper(pattern[0])=='A')
895 grid_ptr->align_auto = AA_ASS;
896 else if (toupper(pattern[0])=='D')
897 grid_ptr->align_auto = AA_DEASS;
898 else if (toupper(pattern[0])=='B')
899 grid_ptr->align_auto = AA_BOTH;
900 else {
901 config_error_ack (trace, "Grid_align must be >0, ASSERTION, or DEASSERTION, or BOTH\n");
902 }
903 }
904 else {
905 value = string_to_time (trace, pattern);
906 grid_ptr->alignment = value;
907 grid_ptr->align_auto = AA_USER;
908 }
909 }
910 else if (!strcmp(cmd, "GRID_TYPE")) {
911 line += config_read_grid (trace, line, &grid_ptr);
912 line += config_read_int (line, &value);
913 if (isalpha(line[0])) { line += config_read_string (trace, line, pattern); }
914 if (grid_ptr) {
915 if (toupper(pattern[0])=='N')
916 grid_ptr->wide_line = FALSE;
917 else if (toupper(pattern[0])=='W')
918 grid_ptr->wide_line = TRUE;
919 else {
920 config_error_ack (trace, "Grid_type must be NORMAL or WIDE\n");
921 }
922 }
923 }
924 else if (!strcmp(cmd, "GRID_SIGNAL")) {
925 line += config_read_grid (trace, line, &grid_ptr);
926 line += config_read_string (trace, line, pattern);
927 if (grid_ptr && *pattern) {
928 strcpy (grid_ptr->signal, pattern);
929 }
930 }
931 else if (!strcmp(cmd, "GRID_COLOR")) {
932 ColorNum_t color;
933 line += config_read_grid (trace, line, &grid_ptr);
934 line += config_read_color (trace, line, &color, TRUE);
935 if (grid_ptr && color>=0) {
936 grid_ptr->color = color;
937 }
938 }
939 else if (!strcmp(cmd, "RISE_FALL_TIME")) {
940 value = global->sigrf;
941 line += config_read_int (line, &value);
942 /* Valid values not known... */
943 global->sigrf = value;
944 }
945 else if (!strcmp(cmd, "PAGE_INC")) {
946 value = global->pageinc;
947 line += config_read_int (line, &value);
948 if (value == 1) global->pageinc = PAGEINC_FULL;
949 else if (value == 2) global->pageinc = PAGEINC_HALF;
950 else if (value == 4) global->pageinc = PAGEINC_QUARTER;
951 else {
952 config_error_ack (trace, "Page_Inc must be 1, 2, or 4\n");
953 }
954 if (DTPRINT_CONFIG) printf ("page_inc = %d\n", global->pageinc);
955 }
956 else if (!strcmp(cmd, "PRINT_SIZE")) {
957 switch (toupper(line[0])) {
958 case 'A':
959 global->print_size = PRINTSIZE_A;
960 break;
961 case 'B':
962 global->print_size = PRINTSIZE_B;
963 break;
964 case 'E':
965 if (strchr (cmd, 'L'))
966 global->print_size = PRINTSIZE_EPSLAND;
967 else global->print_size = PRINTSIZE_EPSPORT;
968 break;
969 default:
970 config_error_ack (trace, "Print_Size must be A, B, EPSLAND, or EPSPORT\n");
971 }
972 }
973 else if (!strcmp(cmd, "SIGNAL_HIGHLIGHT")) {
974 ColorNum_t color;
975 line += config_read_pattern (trace, line, pattern);
976 if (pattern[0]) {
977 line += config_read_color (trace, line, &color, TRUE);
978 if (color >= 0) {
979 sig_wildmat_select (NULL, pattern);
980 sig_highlight_selected (color);
981 }
982 }
983 }
984 else if (!strcmp(cmd, "SIGNAL_NOTE")) {
985 char pattern2[MAXSIGLEN];
986 line += config_read_pattern (trace, line, pattern);
987 line += config_read_string (trace, line, pattern2);
988 if (pattern[0] && pattern2[0]) {
989 sig_wildmat_select (NULL, pattern);
990 sig_note_selected (pattern2);
991 }
992 }
993 else if (!strcmp(cmd, "SIGNAL_RADIX")) {
994 line += config_read_pattern (trace, line, pattern);
995 if (pattern[0]) {
996 Radix_t *radix_ptr;
997 char strg[MAXSIGLEN];
998 line += config_read_string (trace,line, strg);
999 radix_ptr = val_radix_find (strg);
1000 if (radix_ptr==NULL) {
1001 config_error_ack (trace, "Undefined radix name\n");
1002 } else {
1003 sig_wildmat_select (NULL, pattern);
1004 sig_radix_selected (radix_ptr );
1005 }
1006 }
1007 }
1008 else if (!strcmp(cmd, "SIGNAL_WAVEFORM")) {
1009 line += config_read_pattern (trace, line, pattern);
1010 if (pattern[0]) {
1011 Waveform_t waveform = WAVEFORM_DIGITAL;
1012 Boolean_t doit = TRUE;
1013 char strg[MAXSIGLEN];
1014 line += config_read_string (trace,line, strg);
1015 if (0==strcmp (strg, "DIGITAL")) {
1016 waveform = WAVEFORM_DIGITAL;
1017 } else if (0==strcmp (strg, "ANALOG")) {
1018 waveform = WAVEFORM_ANALOG;
1019 } else if (0==strcmp (strg, "ANALOG_SIGNED")) {
1020 waveform = WAVEFORM_ANALOG_SIGNED;
1021 } else {
1022 sprintf (message, "Signal_Waveform must be ANALOG or DIGITAL\n");
1023 config_error_ack (trace, message);
1024 doit = FALSE;
1025 }
1026 if (doit) {
1027 sig_wildmat_select (NULL, pattern);
1028 sig_waveform_selected (waveform);
1029 }
1030 }
1031 }
1032 else if (!strcmp(cmd, "SIGNAL_ADD")) {
1033 char pattern2[MAXSIGLEN];
1034 line += config_read_pattern (trace, line, pattern);
1035 if (pattern[0]) {
1036 ColorNum_t color;
1037 line += config_read_string (trace, line, pattern2);
1038 line += config_read_color (trace, line, &color, FALSE);
1039 sig_wildmat_select (global->deleted_trace_head, pattern);
1040 sig_move_selected (trace, pattern2);
1041 if (color >= 0) {
1042 sig_highlight_selected (color);
1043 }
1044 }
1045 }
1046 else if (!strcmp(cmd, "SIGNAL_MOVE")) {
1047 char pattern2[MAXSIGLEN];
1048 line += config_read_pattern (trace, line, pattern);
1049 if (pattern[0]) {
1050 ColorNum_t color;
1051 line += config_read_pattern (trace, line, pattern2);
1052 line += config_read_color (trace, line, &color, FALSE);
1053 sig_wildmat_select (NULL, pattern);
1054 sig_move_selected (trace, pattern2);
1055 if (color >= 0) {
1056 sig_highlight_selected (color);
1057 }
1058 }
1059 }
1060 else if (!strcmp(cmd, "SIGNAL_RENAME")) {
1061 char pattern2[MAXSIGLEN];
1062 line += config_read_pattern (trace, line, pattern);
1063 line += config_read_pattern (trace, line, pattern2);
1064 if (pattern[0] && pattern2[0]) {
1065 ColorNum_t color;
1066 line += config_read_color (trace, line, &color, FALSE);
1067 sig_wildmat_select (NULL, pattern);
1068 sig_rename_selected (pattern2);
1069 if (color >= 0) {
1070 sig_highlight_selected (color);
1071 }
1072 }
1073 }
1074 else if (!strcmp(cmd, "SIGNAL_COPY")) {
1075 char pattern2[MAXSIGLEN];
1076 line += config_read_pattern (trace, line, pattern);
1077 if (pattern[0]) {
1078 ColorNum_t color;
1079 line += config_read_pattern (trace, line, pattern2);
1080 line += config_read_color (trace, line, &color, FALSE);
1081 sig_wildmat_select (NULL, pattern);
1082 sig_copy_selected (trace, pattern2);
1083 if (color >= 0) {
1084 sig_highlight_selected (color);
1085 }
1086 }
1087 }
1088 else if (!strcmp(cmd, "SIGNAL_DELETE")) {
1089 line += config_read_pattern (trace, line, pattern);
1090 if (pattern[0]) {
1091 sig_wildmat_select (trace, pattern);
1092 sig_delete_selected (TRUE, FALSE);
1093 }
1094 }
1095 else if (!strcmp(cmd, "SIGNAL_DELETE_CONSTANT")) {
1096 char flag[MAXSIGLEN];
1097 Boolean_t ignorexz = FALSE;
1098 line += config_read_pattern (trace, line, pattern);
1099 if (pattern[0]) {
1100 do {
1101 line += config_read_string (trace, line, flag);
1102 if (!strcasecmp(flag, "-IGNOREXZ")) ignorexz=TRUE;
1103 } while (flag[0]);
1104 sig_wildmat_select (trace, pattern);
1105 sig_delete_selected (FALSE, ignorexz);
1106 }
1107 }
1108 else if (!strcmp(cmd, "VALUE_HIGHLIGHT")) {
1109 char strg[MAXSIGLEN],flag[MAXSIGLEN],signal[MAXSIGLEN]="*";
1110 ValSearch_t *vs_ptr;
1111 Boolean_t show_value=FALSE, add_cursor=FALSE;
1112 VSearchNum_t search_pos;
1113 line += config_read_value (trace, line, strg);
1114 line += config_read_color (trace, line, &search_pos, TRUE);
1115 search_pos--;
1116 if (search_pos >= 0) {
1117 do {
1118 line += config_read_string (trace, line, flag);
1119 if (!strcasecmp(flag, "-CURSOR")) add_cursor=TRUE;
1120 else if (!strcasecmp(flag, "-VALUE")) show_value=TRUE;
1121 else if (flag[0]) strcpy (signal, flag);
1122 } while (flag[0]);
1123 /* Add it */
1124 vs_ptr = &global->val_srch[search_pos];
1125 vs_ptr->color = (show_value) ? search_pos+1 : 0;
1126 vs_ptr->cursor = (add_cursor) ? search_pos+1 : 0;
1127 string_to_value (&vs_ptr->radix, strg, &vs_ptr->value);
1128 strcpy (vs_ptr->signal, signal);
1129 draw_needupd_val_search ();
1130 }
1131 }
1132 else if (!strcmp(cmd, "CURSOR_ADD")) {
1133 ColorNum_t color;
1134 DTime_t ctime;
1135 char strg[MAXSIGLEN],flag[MAXSIGLEN];
1136 char note[MAXSIGLEN]="";
1137 CursorType_t type = CONFIG;
1138
1139 line += config_read_string (trace, line, strg);
1140 ctime = string_to_time (trace, strg);
1141 line += config_read_color (trace, line, &color, TRUE);
1142 if (color >= 0) {
1143 do {
1144 line += config_read_string (trace, line, flag);
1145 if (!strcasecmp(flag, "-USER")) type=USER;
1146 else if (!strcasecmp(flag, "-SIMVIEW") && global->simview_info_ptr) type=SIMVIEW;
1147 else if (flag[0]) strcpy (note, flag);
1148 } while (flag[0]);
1149 cur_new (ctime, color, type, note);
1150 }
1151 }
1152 else if (!strcmp(cmd, "CURSOR_STEP_FORWARD")) {
1153 cur_step (grid_primary_period (trace));
1154 }
1155 else if (!strcmp(cmd, "CURSOR_STEP_BACKWARD")) {
1156 cur_step ( - grid_primary_period (trace));
1157 }
1158 else if (!strcmp(cmd, "TIME_GOTO")) {
1159 DTime_t ctime;
1160 char strg[MAXSIGLEN];
1161 DTime_t end_time = global->time + (DTime_t)(( trace->width - XMARGIN - global->xstart ) / global->res);
1162
1163 line += config_read_string (trace, line, strg);
1164 ctime = string_to_time (trace, strg);
1165
1166 if ((ctime < global->time) || (ctime > end_time)) {
1167 /* Slide time if it isn't on the screen already */
1168 global->time = ctime - ( TIME_WIDTH (trace) /2 );
1169 new_time (trace);
1170 }
1171 }
1172 else if (!strcmp(cmd, "RESOLUTION")) {
1173 DTime_t restime;
1174 char strg[MAXSIGLEN];
1175
1176 line += config_read_string (trace, line, strg);
1177 restime = string_to_time (trace, strg);
1178
1179 if (restime > 0) {
1180 new_res (trace, RES_SCALE / (float)restime);
1181 }
1182 }
1183 else if (!strcmp(cmd, "SIGNAL_GOTO")) {
1184 line += config_read_pattern (trace, line, pattern);
1185 if (pattern[0]) {
1186 sig_goto_pattern (trace, pattern);
1187 }
1188 }
1189 else if (!strcmp(cmd, "REFRESH")) {
1190 draw_all_needed ();
1191 draw_manual_needed ();
1192 /* Main loop won't refresh because widget's weren't activated on socket calls */
1193 if (config_reading_socket) {
1194 draw_perform();
1195 }
1196 }
1197 else if (!strcmp(cmd, "ANNOTATE")) {
1198 val_annotate_do_cb (NULL,trace,NULL);
1199 }
1200 else if (!strcmp(cmd, "START_GEOMETRY")) {
1201 if (*line=='"') line++;
1202 config_parse_geometry (line, &(global->start_geometry));
1203 }
1204 else if (!strcmp(cmd, "OPEN_GEOMETRY")) {
1205 if (*line=='"') line++;
1206 config_parse_geometry (line, &(global->open_geometry));
1207 }
1208 else if (!strcmp(cmd, "SHRINK_GEOMETRY")) {
1209 if (*line=='"') line++;
1210 config_parse_geometry (line, &(global->shrink_geometry));
1211 }
1212 else if (!strcmp(cmd, "SIGNAL_STATES")) {
1213 memset (&newsigst, 0, sizeof (SignalState_t));
1214 line += config_read_pattern (trace, line, newsigst.signame);
1215 processing_sig_state = TRUE;
1216 /* if (DTPRINT) printf ("config_process_states signal=%s\n", newsigst.signame); */
1217 goto re_process_line;
1218 }
1219 else {
1220 sprintf (message, "Unknown command '%s'\n", cmd);
1221 config_error_ack (trace, message);
1222 }
1223 }
1224 }
1225
1226 /* Normal call */
1227 #define config_process_line(trace, line, fmt) config_process_line_internal(trace, line, fmt, FALSE)
1228
1229 /* EOF */
config_process_eof(Trace_t * trace)1230 static void config_process_eof (Trace_t *trace)
1231 {
1232 char line[3];
1233 line[0]='\0'; /* MIPS: no automatic aggregate initialization */
1234 line[1]='\0';
1235 line[2]='\0';
1236 config_process_line_internal (trace, line, FALSE, TRUE);
1237 }
1238
1239 /**********************************************************************
1240 * config_read_file
1241 **********************************************************************/
1242
config_read_file(Trace_t * trace,char * filename,Boolean_t report_notfound,Boolean_t format_only)1243 void config_read_file (
1244 Trace_t *trace,
1245 char *filename, /* Specific filename of CONFIG file */
1246 Boolean_t report_notfound,
1247 Boolean_t format_only)
1248 {
1249 FILE *readfp;
1250 char line[1000];
1251 struct stat newstat; /* New status on the reread file*/
1252 int read_fd;
1253 int prev_cursor;
1254
1255 if (DTPRINT_CONFIG || DTPRINT_ENTRY) printf("Reading config file %s\n", filename);
1256
1257 if (filename[strlen(filename)-1] == '/') {
1258 /* Ignore it, It's a directory */
1259 return;
1260 }
1261
1262 config_report_errors = !format_only;
1263
1264 #ifndef VMS
1265 /* Check if regular file (not directory) */
1266 read_fd = open (filename, O_RDONLY, 0);
1267 if (read_fd>0) {
1268 fstat (read_fd, &newstat);
1269 if (! S_ISREG(newstat.st_mode)) {
1270 /* Not regular file */
1271 read_fd = -1;
1272 }
1273 close (read_fd);
1274 }
1275 #endif
1276
1277 /* Open File For Reading */
1278 if (!(readfp=fopen(filename,"r"))) {
1279 read_fd = -1;
1280 }
1281
1282 if (read_fd < 0) {
1283 if (report_notfound) {
1284 if (DTPRINT) printf("%%E, Can't Open File %s\n", filename);
1285 sprintf(message,"Can't open file %s",filename);
1286 dino_error_ack(trace, message);
1287 }
1288 return;
1289 }
1290
1291 prev_cursor = last_set_cursor ();
1292 set_cursor (DC_BUSY);
1293
1294 config_line_num=0;
1295 config_file = filename;
1296 config_reading_socket = FALSE;
1297 while (!feof(readfp)) {
1298 /* Read line & kill EOL at end */
1299 config_get_line (line, 1000, readfp);
1300 /* printf ("line='%s'\n",line); */
1301 config_process_line (trace, line, format_only);
1302 }
1303
1304 config_process_eof (trace);
1305
1306 fclose (readfp);
1307 set_cursor (prev_cursor);
1308 }
1309
1310 /**********************************************************************
1311 * config_read_socket
1312 **********************************************************************/
1313
config_read_socket(char * line,char * name,int cmdnum,Boolean_t eof)1314 void config_read_socket (
1315 char *line,
1316 char *name,
1317 int cmdnum,
1318 Boolean_t eof
1319 )
1320 {
1321 config_report_errors = TRUE;
1322 config_line_num = cmdnum;
1323 config_file = name;
1324 config_reading_socket = TRUE;
1325
1326 if (eof) {
1327 config_process_eof (global->trace_head);
1328 }
1329 else {
1330 config_process_line (global->trace_head, line, FALSE);
1331 }
1332 }
1333
1334 /**********************************************************************
1335 **********************************************************************/
1336
config_update_filenames(Trace_t * trace)1337 void config_update_filenames (Trace_t *trace)
1338 {
1339 if (DTPRINT_ENTRY) printf ("In config_update_filenames\n");
1340
1341 global->config_filename[3][0] = '\0';
1342 global->config_filename[4][0] = '\0';
1343
1344 /* Same directory as trace, dinotrace.dino */
1345 if (trace->dfile.filename != '\0') {
1346 strcpy (global->config_filename[3], trace->dfile.filename);
1347 file_directory (global->config_filename[3]);
1348 strcat (global->config_filename[3], "dinotrace.dino");
1349 }
1350
1351 /* Same file as trace, but .dino extension */
1352 if (trace->dfile.filename != '\0') {
1353 char *slash;
1354 char *pchar;
1355 strcpy (global->config_filename[4], trace->dfile.filename);
1356 slash = strrchr (global->config_filename[4],'/');
1357 if (slash==NULL) slash = global->config_filename[4];
1358 while ((pchar=strrchr(slash,'.')) != NULL) {
1359 *pchar = '\0';
1360 }
1361 strcat (global->config_filename[4], ".dino");
1362 }
1363 }
1364
config_read_defaults(Trace_t * trace,Boolean_t format_only)1365 void config_read_defaults (
1366 Trace_t *trace,
1367 Boolean_t format_only)
1368 {
1369 int cfg_num;
1370 Signal_t *new_dispsig;
1371 Signal_t *sig_ptr;
1372
1373 if (DTPRINT_ENTRY) printf ("In config_read_defaults\n");
1374
1375 new_dispsig = trace->dispsig;
1376
1377 /* Erase old cursors */
1378 cur_delete_of_type (CONFIG);
1379
1380 config_update_filenames(trace);
1381
1382 for (cfg_num=0; cfg_num<MAXCFGFILES; cfg_num++) {
1383 if ( global->config_enable[cfg_num] ) {
1384 config_read_file (trace, global->config_filename[cfg_num], FALSE, format_only);
1385 }
1386 }
1387
1388 /* If user deleted and readded signals, we might have reset */
1389 /* dispsig. Attempt to restore */
1390 if (new_dispsig && trace->dispsig == trace->firstsig) {
1391 for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_ptr->forward) {
1392 if (sig_ptr == new_dispsig) {
1393 /* Is still actively displayed (else deleted) */
1394 trace->dispsig = new_dispsig;
1395 vscroll_new (trace, 0);
1396 break;
1397 }
1398 }
1399
1400 }
1401
1402 /* Apply the statenames */
1403 grid_calc_autos (trace);
1404
1405 draw_all_needed ();
1406 if (DTPRINT_ENTRY) printf ("Exit config_read_defaults\n");
1407 }
1408
1409 /**********************************************************************
1410 * config_writing
1411 **********************************************************************/
1412
config_write_file(Trace_t * trace,char * filename)1413 void config_write_file (
1414 Trace_t *trace,
1415 char *filename) /* Specific filename of CONFIG file */
1416 {
1417 FILE *writefp;
1418 Signal_t *sig_ptr;
1419 int grid_num;
1420 Grid_t *grid_ptr;
1421 int i;
1422 char strg[MAXSIGLEN];
1423 const char *c; /* Comment or null */
1424 Trace_t *trace_top = trace;
1425
1426 if (DTPRINT_CONFIG || DTPRINT_ENTRY) printf("Writing config file %s\n", filename);
1427
1428 /* Open File For Writing */
1429 if (!(writefp=fopen(filename,"w"))) {
1430 if (DTPRINT) printf("%%E, Can't Write File %s\n", filename);
1431 sprintf(message,"Can't write file %s",filename);
1432 dino_error_ack(trace, message);
1433 return;
1434 }
1435
1436 c = (global->cuswr_item[CUSWRITEM_COMMENT]) ? "#" : "";
1437
1438 fprintf (writefp, "##### Customization Write by %s\n", DTVERSION);
1439 fprintf (writefp, "##### Created %s\n", date_string(0));
1440
1441 if (global->cuswr_item[CUSWRITEM_PERSONAL]) {
1442 fprintf (writefp, "\n#### Global Personal Preferences ####\n");
1443 if (DTDEBUG) {
1444 fprintf (writefp, "%sdebug\t\t%s\n", c, DTDEBUG?"ON":"OFF");
1445 /*fprintf (writefp, "%sprint\t\t%x\n", c, DTPRINT?DTPRINT:"OFF"); prints too much on reread*/
1446 }
1447 fprintf (writefp, "%srefreshing\t%s\n", c, global->redraw_manually?"MANUAL":"AUTO");
1448 fprintf (writefp, "%sdraw_prefix\t%s\n", c, global->prefix_enable?"ON":"OFF");
1449 fprintf (writefp, "%ssave_enables\t%s\n", c, global->save_enables?"ON":"OFF");
1450 fprintf (writefp, "%ssave_ordering\t%s\n", c, global->save_ordering?"ON":"OFF");
1451 fprintf (writefp, "%ssave_duplicates\t%s\n", c, global->save_duplicates?"ON":"OFF");
1452 fprintf (writefp, "%sclick_to_edge\t%s\n", c, global->click_to_edge?"ON":"OFF");
1453 fprintf (writefp, "%ssignal_height\t%d\n", c, global->sighgt);
1454 fprintf (writefp, "%srise_fall_time\t%d\n", c, global->sigrf);
1455 fprintf (writefp, "%stime_rep\t%s\n", c, time_units_to_string (global->timerep, TRUE));
1456 fprintf (writefp, "%scursor\t\t%s\n", c, global->cursor_vis?"ON":"OFF");
1457 fprintf (writefp, "%spage_inc\t%d\n", c,
1458 global->pageinc==PAGEINC_QUARTER ? 4 : (global->pageinc==PAGEINC_HALF?2:1) );
1459 fprintf (writefp, "%sprint_size\t", c);
1460 switch (global->print_size) {
1461 case PRINTSIZE_A: fprintf (writefp, "A\n"); break;
1462 case PRINTSIZE_B: fprintf (writefp, "B\n"); break;
1463 case PRINTSIZE_EPSLAND: fprintf (writefp, "EPSLAND\n"); break;
1464 case PRINTSIZE_EPSPORT: fprintf (writefp, "EPSPORT\n"); break;
1465 }
1466
1467 config_geometry_string (&global->start_geometry, strg);
1468 fprintf (writefp, "%sstart_geometry\t%s\n",c, strg);
1469 config_geometry_string (&global->open_geometry, strg);
1470 fprintf (writefp, "%sopen_geometry\t%s\n",c, strg);
1471 config_geometry_string (&global->shrink_geometry, strg);
1472 fprintf (writefp, "%sshrink_geometry\t%s\n",c, strg);
1473
1474 if (global->time_format[0])
1475 fprintf (writefp, "%stime_format\t%s\n",c, global->time_format);
1476
1477 signalstate_write (writefp, c);
1478 }
1479
1480 if (global->cuswr_item[CUSWRITEM_VALSEARCH]) {
1481 fprintf (writefp, "\n#### Value Searches ####\n");
1482 for (i=1; i<=MAX_SRCH; i++) {
1483 ValSearch_t *vs_ptr = &global->val_srch[i-1];
1484 char strg[MAXSIGLEN];
1485 if (vs_ptr->color || vs_ptr->cursor) {
1486 val_to_string (vs_ptr->radix, strg, &vs_ptr->value, 0, FALSE, TRUE);
1487 fprintf (writefp, "%svalue_highlight %s %d \"%s\" %s %s\n",c,
1488 strg, i, vs_ptr->signal,
1489 vs_ptr->color ? "-VALUE":"",
1490 vs_ptr->cursor ? "-CURSOR":"");
1491 }
1492 }
1493 }
1494
1495 if (global->cuswr_item[CUSWRITEM_CURSORS]) {
1496 fprintf (writefp, "\n#### Cursors ####\n");
1497 cur_write (writefp, c);
1498 }
1499
1500 if (global->cuswr_item[CUSWRITEM_FORMAT]) {
1501 fprintf (writefp, "\n#### Trace Format ####\n");
1502 for (trace = global->trace_head; trace; trace = trace->next_trace) {
1503 if (( global->cuswr_traces == TRACESEL_THIS && trace!=trace_top)
1504 || (global->cuswr_traces == TRACESEL_ALL && trace==global->deleted_trace_head)) {
1505 continue;
1506 }
1507 if (trace->loaded) {
1508 fprintf (writefp, "###set_trace\t%s\n", trace->dfile.filename);
1509 fprintf (writefp, "%sfile_format\t%s\n",c, filetypes[trace->dfile.fileformat].name);
1510 fprintf (writefp, "%svector_separator\t\"%c\"\n",c, trace->dfile.vector_separator);
1511 fprintf (writefp, "%shierarchy_separator\t\"%c\"\n",c, trace->dfile.hierarchy_separator);
1512 fprintf (writefp, "%stime_multiplier\t%d\n",c, global->tempest_time_mult);
1513 fprintf (writefp, "%stime_precision\t%s\n",c, time_units_to_string (global->time_precision, TRUE));
1514 }
1515 }
1516 }
1517
1518 if (global->cuswr_item[CUSWRITEM_GRIDS]) {
1519 fprintf (writefp, "\n#### Grids ####\n");
1520 for (trace = global->trace_head; trace; trace = trace->next_trace) {
1521 if (( global->cuswr_traces == TRACESEL_THIS && trace!=trace_top)
1522 || (global->cuswr_traces == TRACESEL_ALL && trace==global->deleted_trace_head)) {
1523 continue;
1524 }
1525 if (trace->loaded) {
1526 fprintf (writefp, "###set_trace\t%s\n", trace->dfile.filename);
1527 for (grid_num=0; grid_num<MAXGRIDS; grid_num++) {
1528 grid_ptr = &(trace->grid[grid_num]);
1529
1530 fprintf (writefp, "%sgrid\t\t%d\t%s\n",c, grid_num, grid_ptr->visible?"ON":"OFF");
1531 fprintf (writefp, "%sgrid_type\t%d\t%s\n",c, grid_num, grid_ptr->wide_line?"WIDE":"NORMAL");
1532 fprintf (writefp, "%sgrid_signal\t%d\t\"%s\"\n",c, grid_num, grid_ptr->signal);
1533 fprintf (writefp, "%sgrid_color\t%d\t%d\n",c, grid_num, grid_ptr->color);
1534 fprintf (writefp, "%sgrid_resolution\t%d\t",c, grid_num);
1535 switch (grid_ptr->period_auto) {
1536 case PA_AUTO: fprintf (writefp, "ASSERTION\n"); break;
1537 default: fprintf (writefp, "%d\n", grid_ptr->period); break;
1538 }
1539 fprintf (writefp, "%sgrid_align\t%d\t",c, grid_num);
1540 switch (grid_ptr->align_auto) {
1541 case AA_ASS: fprintf (writefp, "ASSERTION\n"); break;
1542 case AA_DEASS: fprintf (writefp, "DEASSERTION\n"); break;
1543 default: fprintf (writefp, "%d\n", grid_ptr->alignment); break;
1544 }
1545 }
1546 }
1547 }
1548 }
1549
1550 if (global->cuswr_item[CUSWRITEM_SIGHIGHLIGHT]) {
1551 fprintf (writefp, "\n#### Signal Highlighting, Commenting, etc ####\n");
1552 for (trace = global->deleted_trace_head; trace; trace = trace->next_trace) {
1553 if (( global->cuswr_traces == TRACESEL_THIS && trace!=trace_top)
1554 || (global->cuswr_traces == TRACESEL_ALL && trace==global->deleted_trace_head)) {
1555 continue;
1556 }
1557 fprintf (writefp, "###set_trace %s\n", trace->dfile.filename);
1558 /* Save signal colors */
1559 for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_ptr->forward) {
1560 if (sig_ptr->color && !sig_ptr->search) {
1561 fprintf (writefp, "%ssignal_highlight %s %d\n",c, sig_ptr->signame, sig_ptr->color);
1562 }
1563 if (sig_ptr->note) fprintf (writefp, "%ssignal_note %s \"%s\"\n",c, sig_ptr->signame, sig_ptr->note);
1564 if (sig_ptr->radix != global->radixs[0]) {
1565 fprintf (writefp, "%ssignal_radix %s %s\n",c, sig_ptr->signame, sig_ptr->radix->name);
1566 }
1567 }
1568 }
1569 }
1570
1571 if (global->cuswr_item[CUSWRITEM_SIGORDER]) {
1572 fprintf (writefp, "\n#### Signal Ordering ####\n");
1573 for (trace = global->trace_head; trace; trace = trace->next_trace) {
1574 if (( global->cuswr_traces == TRACESEL_THIS && trace!=trace_top)
1575 || (global->cuswr_traces == TRACESEL_ALL && trace==global->deleted_trace_head)) {
1576 continue;
1577 }
1578 fprintf (writefp, "###set_trace %s\n", trace->dfile.filename);
1579 fprintf (writefp, "%ssignal_delete *\n",c);
1580 /* Save signal colors */
1581 for (sig_ptr = trace->firstsig; sig_ptr; sig_ptr = sig_ptr->forward) {
1582 fprintf (writefp, "%ssignal_add %s\n",c, sig_ptr->signame);
1583 }
1584 }
1585 }
1586
1587 fprintf (writefp, "\n\n##### Customization Write by %s\n", DTVERSION);
1588 fprintf (writefp, "##### Created %s\n", date_string(0));
1589
1590 fclose (writefp);
1591 }
1592
1593 /**********************************************************************
1594 * config_restore_defaults
1595 **********************************************************************/
1596
config_trace_defaults(Trace_t * trace)1597 void config_trace_defaults (
1598 Trace_t *trace)
1599 {
1600 trace->dfile.hierarchy_separator = '.';
1601 trace->dfile.vector_separator = '[';
1602 trace->dfile.vectorend_separator = ']';
1603
1604 grid_reset_cb (trace->main);
1605 }
1606
1607
config_global_defaults(void)1608 void config_global_defaults(void)
1609 {
1610 signalstate_free ();
1611 draw_needupd_val_states ();
1612 draw_needupd_sig_start ();
1613
1614 global->sighgt = 15;
1615 global->pageinc = PAGEINC_FULL;
1616 global->save_ordering = TRUE;
1617 global->cursor_vis = TRUE;
1618 global->sigrf = SIG_RF;
1619 global->timerep = global->time_precision;
1620 }
1621
1622
1623