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