msg_sys.def revision 1.10 1 /* $NetBSD: msg_sys.def,v 1.10 1999/07/04 07:40:51 cgd Exp $ */
2
3 /*
4 * Copyright 1997 Piermont Information Systems Inc.
5 * All rights reserved.
6 *
7 * Written by Philip A. Nelson for Piermont Information Systems Inc.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software develooped for the NetBSD Project by
20 * Piermont Information Systems Inc.
21 * 4. The name of Piermont Information Systems Inc. may not be used to endorse
22 * or promote products derived from this software without specific prior
23 * written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
35 * THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 */
38
39 static WINDOW *msg_win = NULL;
40 static char *cbuffer;
41 static size_t cbuffersize;
42 static int do_echo = 1;
43
44 static int last_i_was_nl, last_i_was_space;
45 static int last_o_was_punct, last_o_was_space;
46
47 /* Routines */
48
49 void msg_beep (void)
50 {
51 fprintf (stderr, "\a");
52 }
53
54 int msg_window(WINDOW *window)
55 {
56 size_t ncbuffersize;
57 char *ncbuffer;
58
59 msg_win = window;
60
61 ncbuffersize = getmaxx(window) * getmaxy(window) + 1;
62 if (ncbuffersize > cbuffersize) {
63 ncbuffer = malloc(ncbuffersize);
64 if (ncbuffer == NULL)
65 return 1;
66 if (cbuffer != NULL)
67 free(cbuffer);
68 cbuffer = ncbuffer;
69 cbuffersize = ncbuffersize;
70 }
71 return 0;
72 }
73
74 char *msg_string (int msg_no)
75 {
76 return msg_list[msg_no];
77 }
78
79 void msg_clear(void)
80 {
81 wclear (msg_win);
82 wrefresh (msg_win);
83 last_o_was_punct = 0;
84 last_o_was_space = 1;
85 }
86
87 void msg_standout(void)
88 {
89 wstandout(msg_win);
90 }
91
92 void msg_standend(void)
93 {
94 wstandend(msg_win);
95 }
96
97 int msg_vprintf (int auto_fill, char *fmt, va_list ap)
98 {
99 const char *wstart, *afterw;
100 int wordlen, nspaces;
101 int ret;
102
103 ret = vsnprintf (cbuffer, cbuffersize, fmt, ap);
104
105 if (!auto_fill) {
106 waddstr(msg_win, cbuffer);
107
108 /*
109 * nothing is perfect if they flow text after a table,
110 * but this may be decent.
111 */
112 last_i_was_nl = last_i_was_space = 1;
113 last_o_was_punct = 0;
114 last_o_was_space = 1;
115 goto out;
116 }
117
118 for (wstart = afterw = cbuffer; *wstart; wstart = afterw) {
119
120 /* eat one space, or a whole word of non-spaces */
121 if (isspace(*afterw))
122 afterw++;
123 else
124 while (*afterw && !isspace(*afterw))
125 afterw++;
126
127 /* this is an nl: special formatting necessary */
128 if (*wstart == '\n') {
129 if (last_i_was_nl || last_i_was_space) {
130
131 if (getcurx(msg_win) != 0)
132 waddch(msg_win, '\n');
133 if (last_i_was_nl) {
134 /* last was an nl: paragraph break */
135 waddch(msg_win, '\n');
136 } else {
137 /* last was space: line break */
138 }
139 last_o_was_punct = 0;
140 last_o_was_space = 1;
141 } else {
142 /* last_o_was_punct unchanged */
143 /* last_o_was_space unchanged */
144 }
145 last_i_was_space = 1;
146 last_i_was_nl = 1;
147 continue;
148 }
149
150 /* this is a tab: special formatting necessary. */
151 if (*wstart == '\t') {
152 if (last_i_was_nl) {
153 /* last was an nl: list indent */
154 if (getcurx(msg_win) != 0)
155 waddch(msg_win, '\n');
156 } else {
157 /* last was not an nl: columns */
158 }
159 waddch(msg_win, '\t');
160 last_i_was_nl = 0;
161 last_i_was_space = 1;
162 last_o_was_punct = 0;
163 last_o_was_space = 1;
164 continue;
165 }
166
167 /* this is a space: ignore it but set flags */
168 last_i_was_nl = 0; /* all newlines handled above */
169 last_i_was_space = isspace(*wstart);
170 if (last_i_was_space)
171 continue;
172
173 /*
174 * we have a real "word," i.e. a sequence of non-space
175 * characters. wstart is now the start of the word,
176 * afterw is the next character after the end.
177 */
178 wordlen = afterw - wstart;
179 nspaces = last_o_was_space ? 0 : (last_o_was_punct ? 2 : 1);
180 if ((getcurx(msg_win) + nspaces + wordlen) >=
181 getmaxx(msg_win) &&
182 wordlen < (getmaxx(msg_win) / 3)) {
183 /* wrap the line */
184 waddch(msg_win, '\n');
185 nspaces = 0;
186 }
187
188 /* output the word, preceded by spaces if necessary */
189 while (nspaces-- > 0)
190 waddch(msg_win, ' ');
191 waddbytes(msg_win, wstart, wordlen);
192
193 /* set up the 'last' state for the next time around */
194 switch (afterw[-1]) {
195 case '.':
196 case '?':
197 case '!':
198 last_o_was_punct = 1;
199 break;
200 default:
201 last_o_was_punct = 0;
202 break;
203 }
204 last_o_was_space = 0;
205
206 /* ... and do it all again! */
207 }
208
209 /* String ended with a newline. They really want a line break. */
210 if (last_i_was_nl) {
211 if (getcurx(msg_win) != 0)
212 waddch(msg_win, '\n');
213 last_o_was_punct = 0;
214 last_o_was_space = 1;
215 }
216
217 out:
218 wrefresh (msg_win);
219 return ret;
220 }
221
222 void msg_display(int msg_no, ...)
223 {
224 va_list ap;
225
226 msg_clear();
227
228 va_start(ap, msg_no);
229 (void)msg_vprintf(0/*XXX*/, msg_list[msg_no], ap);
230 va_end(ap);
231 }
232
233 void msg_display_add(int msg_no, ...)
234 {
235 va_list ap;
236
237 va_start (ap, msg_no);
238 (void)msg_vprintf(0/*XXX*/, msg_list[msg_no], ap);
239 va_end (ap);
240 }
241
242 int msg_printf (char *fmt, ...)
243 {
244 va_list ap;
245 int res;
246
247 msg_clear();
248
249 va_start (ap, fmt);
250 res = msg_vprintf (0/*XXX*/, fmt, ap);
251 va_end (ap);
252 return res;
253 }
254
255 int msg_printf_add (char *fmt, ...)
256 {
257 va_list ap;
258 int res;
259
260 va_start (ap, fmt);
261 res = msg_vprintf (0/*XXX*/, fmt, ap);
262 va_end (ap);
263 return res;
264 }
265
266
267 static void msg_vprompt (char *msg, char *def, char *val, int max_chars,
268 va_list ap)
269 {
270 int ch;
271 int count = 0;
272 int y,x;
273 char *ibuf = alloca(max_chars);
274
275 msg_vprintf (0, msg, ap);
276 if (def != NULL && *def) {
277 waddstr (msg_win, " [");
278 waddstr (msg_win, def);
279 waddstr (msg_win, "]");
280 }
281 waddstr (msg_win, ": ");
282 wrefresh (msg_win);
283
284 while ((ch = wgetch(msg_win)) != '\n') {
285 if (ch == 0x08 || ch == 0x7f) { /* bs or del */
286 if (count > 0) {
287 count--;
288 if (do_echo) {
289 getyx(msg_win, y, x);
290 x--;
291 wmove(msg_win, y, x);
292 wdelch(msg_win);
293 }
294 } else
295 msg_beep ();
296 } else if (ch == 0x15) { /* ^U; line kill */
297 while (count > 0) {
298 count--;
299 if (do_echo) {
300 getyx(msg_win, y, x);
301 x--;
302 wmove(msg_win, y, x);
303 wdelch(msg_win);
304 }
305 }
306 } else if (ch == 0x17) { /* ^W; word kill */
307 /*
308 * word kill kills the spaces and the 'word'
309 * (non-spaces) last typed. the spaces before
310 * the 'word' aren't killed.
311 */
312 while (count > 0 && isspace(ibuf[count - 1])) {
313 count--;
314 if (do_echo) {
315 getyx(msg_win, y, x);
316 x--;
317 wmove(msg_win, y, x);
318 wdelch(msg_win);
319 }
320 }
321 while (count > 0 && !isspace(ibuf[count - 1])) {
322 count--;
323 if (do_echo) {
324 getyx(msg_win, y, x);
325 x--;
326 wmove(msg_win, y, x);
327 wdelch(msg_win);
328 }
329 }
330 } else if (count < (max_chars - 1) && isprint(ch)) {
331 if (do_echo)
332 waddch (msg_win, ch);
333 ibuf[count++] = ch;
334 } else
335 msg_beep ();
336 if (do_echo)
337 wrefresh(msg_win);
338 }
339 if (do_echo) {
340 waddch(msg_win, '\n');
341 last_o_was_punct = 0;
342 last_o_was_space = 1;
343 }
344
345 /* copy the appropriate string to the output */
346 if (count != 0) {
347 ibuf[count] = '\0';
348 strcpy(val, ibuf); /* size known to be OK */
349 } else if (def != NULL && val != def) {
350 strncpy(val, def, max_chars);
351 val[max_chars - 1] = '\0';
352 }
353 }
354
355 void msg_prompt_addstr (char *fmt, char *def, char *val, int max_chars, ...)
356 {
357 va_list ap;
358
359 va_start (ap, max_chars);
360 msg_vprompt (fmt, def, val, max_chars, ap);
361 va_end(ap);
362 }
363
364 void msg_prompt_add (int msg_no, char *def, char *val, int max_chars, ...)
365 {
366 va_list ap;
367
368 va_start (ap, max_chars);
369 msg_vprompt (msg_list[msg_no], def, val, max_chars, ap);
370 va_end(ap);
371 }
372
373 void msg_prompt_str (char *msg, char *def, char *val, int max_chars, ...)
374 {
375 va_list ap;
376
377 msg_clear();
378
379 va_start (ap, max_chars);
380 msg_vprompt (msg, def, val, max_chars, ap);
381 va_end (ap);
382 }
383
384 void msg_prompt (int msg_no, char *def, char *val, int max_chars, ...)
385 {
386 va_list ap;
387
388 msg_clear();
389
390 va_start (ap, max_chars);
391 msg_vprompt (msg_list[msg_no], def, val, max_chars, ap);
392 va_end (ap);
393 }
394
395 void msg_noecho()
396 {
397 do_echo = 0;
398 }
399
400 void msg_echo()
401 {
402 do_echo = 1;
403 }
404
405 void msg_table(int msg_no, ...)
406 {
407 va_list ap;
408
409 msg_clear();
410
411 va_start(ap, msg_no);
412 (void)msg_vprintf(0, msg_list[msg_no], ap);
413 va_end(ap);
414 }
415
416 void msg_table_add(int msg_no, ...)
417 {
418 va_list ap;
419
420 va_start (ap, msg_no);
421 (void)msg_vprintf(0, msg_list[msg_no], ap);
422 va_end (ap);
423 }
424
425