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