1 /* -*- tab-width: 4 -*-
2 *
3 * Electric(tm) VLSI Design System
4 *
5 * File: dbterminal.c
6 * General messages terminal output handler
7 * Written by: Steven M. Rubin, Static Free Software
8 *
9 * Copyright (c) 2000 Static Free Software.
10 *
11 * Electric(tm) is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * Electric(tm) is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with Electric(tm); see the file COPYING. If not, write to
23 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
24 * Boston, Mass 02111-1307, USA.
25 *
26 * Static Free Software
27 * 4119 Alpine Road
28 * Portola Valley, California 94028
29 * info@staticfreesoft.com
30 */
31
32 #include "global.h"
33 #include "usr.h"
34 #include "edialogs.h"
35
36 static INTBIG us_ttymute = 0; /* nonzero to supress unimportant messages */
37 static INTBIG us_ttyttywriteseparator = 0; /* nonzero to write separator before next text */
38 static INTBIG us_sepcount = 0; /* index of separator lines */
39
40 /***************************** TERMINAL OUTPUT *****************************/
41
42 /*
43 * routine to mute nonerror messages if flag is nonzero
44 * (returns previous state)
45 */
ttyquiet(INTBIG flag)46 INTBIG ttyquiet(INTBIG flag)
47 {
48 REGISTER INTBIG prev;
49
50 prev = us_ttymute;
51 us_ttymute = flag;
52 return(prev);
53 }
54
ttynewcommand(void)55 void ttynewcommand(void)
56 {
57 us_ttyttywriteseparator = 1;
58 }
59
60 /*
61 * routine to output a normal message into the messages window
62 * in the style of "printf"
63 */
ttyputmsg(CHAR * msg,...)64 void ttyputmsg(CHAR *msg, ...)
65 {
66 va_list ap;
67
68 /* don't print or save this message if muted */
69 if (us_ttymute != 0) return;
70
71 /* don't print this message if quit or aborted */
72 if (el_pleasestop != 0) return;
73
74 var_start(ap, msg);
75 us_ttyprint(FALSE, msg, ap);
76 va_end(ap);
77 }
78
79 /*
80 * routine to output a "verbose" message (those that provide unimportant
81 * information that can be done without) into the messages window
82 * in the style of "printf"
83 */
ttyputverbose(CHAR * msg,...)84 void ttyputverbose(CHAR *msg, ...)
85 {
86 va_list ap;
87
88 /* ignore this message if facts are turned off */
89 if ((us_tool->toolstate&JUSTTHEFACTS) != 0) return;
90
91 /* don't print or save this message if muted */
92 if (us_ttymute != 0) return;
93
94 /* don't print this message if quit or aborted */
95 if (el_pleasestop != 0) return;
96
97 var_start(ap, msg);
98 us_ttyprint(FALSE, msg, ap);
99 va_end(ap);
100 }
101
102 /*
103 * routine to output an error message into the messages window
104 * in the style of "printf"
105 */
ttyputerr(CHAR * msg,...)106 void ttyputerr(CHAR *msg, ...)
107 {
108 va_list ap;
109
110 var_start(ap, msg);
111 ttybeep(SOUNDBEEP, FALSE);
112 us_ttyprint(TRUE, msg, ap);
113 va_end(ap);
114 }
115
116 /*
117 * Routine to put out a message that is in 2 parts: a keystroke and a meaning.
118 * The length of the "keystroke" field is "length".
119 */
ttyputinstruction(CHAR * keystroke,INTBIG length,CHAR * meaning)120 void ttyputinstruction(CHAR *keystroke, INTBIG length, CHAR *meaning)
121 {
122 REGISTER INTBIG i;
123 REGISTER void *infstr;
124
125 infstr = initinfstr();
126 for(i=0; i<length; i++)
127 {
128 if (*keystroke == 0) addtoinfstr(infstr, ' '); else
129 addtoinfstr(infstr, *keystroke++);
130 }
131 addstringtoinfstr(infstr, meaning);
132 ttyputmsg(x_("%s"), returninfstr(infstr));
133 }
134
ttyputusage(CHAR * usage)135 void ttyputusage(CHAR *usage)
136 {
137 ttyputerr(_("Usage: %s"), usage);
138 }
139
ttyputbadusage(CHAR * command)140 void ttyputbadusage(CHAR *command)
141 {
142 ttyputerr(_("Bad '%s' command"), command);
143 }
144
ttyputnomemory(void)145 void ttyputnomemory(void)
146 {
147 ttyputerr(_("No memory"));
148 }
149
150 /*
151 * routine to cause the current command to be aborted by removing it from
152 * any macro and by printing the message on the terminal
153 */
us_abortcommand(CHAR * msg,...)154 void us_abortcommand(CHAR *msg, ...)
155 {
156 va_list ap;
157
158 var_start(ap, msg);
159 us_ttyprint(TRUE, msg, ap);
160 va_end(ap);
161 us_state |= COMMANDFAILED;
162 if (getvalkey((INTBIG)us_tool, VTOOL, VSTRING, us_macrobuildingkey) != NOVARIABLE)
163 ttyputmsg(_("Command ignored from macro definition"));
164 us_unknowncommand();
165 }
166
167 /*
168 * routine to cause further single-key commands to be ignored until a
169 * carriage-return is typed.
170 */
us_unknowncommand(void)171 void us_unknowncommand(void)
172 {
173 REGISTER INTBIG i;
174
175 if ((us_tool->toolstate&NOKEYLOCK) != 0) return;
176 i = ttyquiet(0);
177 ttyputmsg(_("Single-key commands will be ignored until the next RETURN"));
178 (void)ttyquiet(i);
179 us_state |= SKIPKEYS;
180 }
181
us_abortedmsg(void)182 void us_abortedmsg(void)
183 {
184 if ((us_tool->toolstate & JUSTTHEFACTS) == 0) us_abortcommand(_("Aborted")); else
185 {
186 us_state |= COMMANDFAILED;
187 if (getvalkey((INTBIG)us_tool, VTOOL, VSTRING, us_macrobuildingkey) != NOVARIABLE)
188 ttyputmsg(_("Command ignored from macro definition"));
189 us_unknowncommand();
190 }
191 }
192
193 /****************************** TERMINAL INPUT ******************************/
194
195 /*
196 * ttygetchar gets the next character from the text keyboard.
197 * The routine must call the graphics module to do input.
198 */
ttygetchar(INTBIG * special)199 INTSML ttygetchar(INTBIG *special)
200 {
201 return(getnxtchar(special));
202 }
203
204 /* ttygetline() Dialog */
205 static DIALOGITEM us_ttyinputdialogitems[] =
206 {
207 /* 1 */ {0, {96,200,120,264}, BUTTON, N_("OK")},
208 /* 2 */ {0, {96,24,120,88}, BUTTON, N_("Cancel")},
209 /* 3 */ {0, {58,38,74,246}, EDITTEXT, x_("")},
210 /* 4 */ {0, {3,9,51,281}, MESSAGE, x_("")}
211 };
212 static DIALOG us_ttyinputdialog = {{50,75,188,371}, x_(""), 0, 4, us_ttyinputdialogitems, 0, 0};
213
214 /* special items for the "ttygetline" dialog: */
215 #define DGTL_LINE 3 /* line (edit text) */
216 #define DGTL_PROMPT 4 /* prompt (stat text) */
217
218 /*
219 * routine to print "prompt" and then read a line of text from the terminal
220 * The address of the text line is returned (0 if cancelled).
221 */
ttygetline(CHAR * prompt)222 CHAR *ttygetline(CHAR *prompt)
223 {
224 INTBIG itemHit;
225 CHAR *line, *pt, *defaultval, localprompt[256];
226 REGISTER void *dia;
227
228 /* parse default value */
229 estrcpy(localprompt, prompt);
230 defaultval = x_("");
231 for(pt=localprompt; *pt != 0; pt++) if (*pt == '[') break;
232 if (*pt != 0)
233 {
234 *pt++ = 0;
235 defaultval = pt;
236 for( ; *pt != 0; pt++) if (*pt == ']') break;
237 if (*pt == ']') *pt = 0;
238 }
239
240 /* display the dialog box */
241 dia = DiaInitDialog(&us_ttyinputdialog);
242 if (dia == 0) return(0);
243 DiaSetText(dia, DGTL_PROMPT, localprompt);
244 DiaSetText(dia, -DGTL_LINE, defaultval);
245
246 /* loop until done */
247 for(;;)
248 {
249 itemHit = DiaNextHit(dia);
250 if (itemHit == CANCEL) break;
251 if (itemHit == OK) break;
252 }
253
254 if (itemHit != CANCEL)
255 line = us_putintoinfstr(DiaGetText(dia, DGTL_LINE));
256
257 /* terminate the dialog */
258 DiaDoneDialog(dia);
259 if (itemHit == CANCEL) return(0);
260 return(line);
261 }
262
263 /*
264 * routine to display "prompt" and then accept a line of text from the
265 * messages window. The address of the text line is returned. Returns
266 * zero if end-of-file is typed (^D).
267 */
ttygetlinemessages(CHAR * prompt)268 CHAR *ttygetlinemessages(CHAR *prompt)
269 {
270 return(getmessagesstring(prompt));
271 }
272
273 /*
274 * Routine to clear the messages window.
275 */
ttyclearmessages(void)276 void ttyclearmessages(void)
277 {
278 clearmessageswindow();
279 us_sepcount = 0;
280 }
281
282 /*
283 * Routine to write information into trace file
284 */
etrace(INTBIG mode,CHAR * s,...)285 void etrace(INTBIG mode, CHAR *s, ...)
286 {
287 va_list ap;
288 CHAR line[500];
289
290 if (us_tracefile == NULL)
291 {
292 us_tracefile = xcreate(x_("trace.txt"), el_filetypetext, 0, 0);
293 if (us_tracefile == NULL) return;
294 }
295
296 /* build the error message */
297 var_start(ap, s);
298 evsnprintf(line, 500, s, ap);
299 va_end(ap);
300
301 efprintf(us_tracefile, line);
302 fflush(us_tracefile);
303 }
304
305 /***************************** INTERNAL SUPPORT *****************************/
306
307 /*
308 * internal routine to print a message in the scrolling area with the
309 * style of "printf". Pops up the messages window if "important" is true.
310 */
us_ttyprint(BOOLEAN important,CHAR * msg,va_list ap)311 void us_ttyprint(BOOLEAN important, CHAR *msg, va_list ap)
312 {
313 CHAR line[8192];
314 REGISTER INTBIG i, j, k;
315
316 if (us_ttyttywriteseparator != 0)
317 {
318 us_sepcount++;
319 esnprintf(line, 8192,
320 x_("================================= %ld ================================="),
321 us_sepcount);
322 putmessagesstring(line, important);
323 if (us_termaudit != 0) xprintf(us_termaudit, x_("%s\n"), line);
324 us_ttyttywriteseparator = 0;
325 }
326
327 /* build the output line */
328 evsnprintf(line, 8192, msg, ap);
329
330 /* remove excessive trailing space */
331 i = estrlen(line);
332 while (i > 1 && (line[i-1] == ' ' || line[i-1] == '\t') &&
333 (line[i-2] == ' ' || line[i-2] == '\t')) line[--i] = 0;
334
335 /* break the line at newline characters */
336 for(k=j=0; j<i; j++)
337 {
338 if (line[j] == '\n')
339 {
340 line[j] = 0;
341 putmessagesstring(&line[k], important);
342 if (us_termaudit != 0) xprintf(us_termaudit, x_("%s\n"), &line[k]);
343 k = j + 1;
344 }
345 }
346
347 if (k < i)
348 {
349 putmessagesstring(&line[k], important);
350 if (us_termaudit != 0) xprintf(us_termaudit, x_("%s\n"), &line[k]);
351 }
352 }
353