allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (06/04/89)
Posting-number: Volume 7, Issue 15 Submitted-by: mott@ucscb.UCSC.EDU (Hung H. Le) Archive-name: my_wgetstr my_wgetstr() is equipvalent to wgetstr() in "curses" but with line editing feature. Will recognize erase, kill and control-w as editing characters. ------------------------------------------------------------ Hung H. Le mott@ucscb.ucsc.edu ...!ucbvax!ucscc!ucscb!mott mott@ucscd.BITNET #include <std_disclaimer> ------------------------------------------------------------ --- Include shar file -- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # README # example.c # makefile # my_wgetstr.c # my_wgetstr.h # This archive created: Sun May 21 10:46:51 1989 # By: Hung H. Le (Uncle Charlie Summer Camp) export PATH; PATH=/bin:$PATH echo shar: extracting "'README'" '(1427 characters)' if test -f 'README' then echo shar: will not over-write existing file "'README'" else sed 's/^ X//' << \SHAR_EOF > 'README' X X I wrote my_wgetstr() as a replacement for wgets() in curses. X XWhat my_getstr() does that wgets() does not? X . line editing as in csh. Erase char, kill char, control-w X are recognized. X . check for overflow. Two possible actions can be taken X 1. returns immediately X 2. bell() to let user know that buffer is full X only newline and editing chars are passed through at X this point X XWhat my_getstr() does not do that wgets() does? X . does not check for illegal scrolling. X XHeader file: X remember to include "my_wgetstr.h" X my_getstr(), RET and NO_RET are defined in there. X XUsage: X n = my_wgetstr(WINDOW *win, char *str, int size, int ret); X win: the concerned window X str: storage for input chars X size: my_wgetstr() will get at most (size - 1) chars. X ret: what to do when buffer is full X 0: bell() X 1: returns X you can use NO_RET or RET X n: number of characters actually gets X X my_getstr(char *str, int size, int ret); X is a macro defined as X#define my_getstr(str, size) my_wgetstr(stdscr, str, size) X in "my_wgetstr.h" X Xmy_wgetstr() returns if X . input is a newline X . if ( (strlen(str) == (size - 1)) and (ret) ) X Xmy_wgetstr() DOES NOT check for illegal scrolling so it is the Xprogrammer's job to take care of that. X XAfter unpack this package. Type "make" to make "example". XTry out "example". X Xwritten by Hung Le Xmott@ucscb.ucsc.edu X...!ucbvax!ucscc!ucscb!mott X X This code is placed in Public Domain. X SHAR_EOF if test 1427 -ne "`wc -c < 'README'`" then echo shar: error transmitting "'README'" '(should have been 1427 characters)' fi fi # end of overwriting check echo shar: extracting "'example.c'" '(2271 characters)' if test -f 'example.c' then echo shar: will not over-write existing file "'example.c'" else sed 's/^ X//' << \SHAR_EOF > 'example.c' X/* X * Example program -- X * A possible replacement for curses' wgetstr(). Allows X * limited editing. Recognizes the erase and kill chars. X * X * By Hung Le (mott@ucscb.ucsc.edu ...!ucbvax!ucscc!ucscb!mott) X * History: X * 01/18/89 - Initial version X * 03/20/89 - add control-w to delete word X * X * Release to Public Domain X */ X X#include <curses.h> X#include <signal.h> X/* REMEMBER to include "my_wgetstr.h" */ X#include "my_wgetstr.h" X X/* test my_wgetstr() */ Xmain() X{ X char buffer[30]; X static char *header[] = X { X "INPUT WINDOW", X "Look Ma ... Line editing in curses", X "Erase char to erase, Kill char to delete the whole line", X "control-w to delete a word, empty input line to quit", X }; X char ender[81], *name, *getlogin(), *getenv(); X int clean_up(), n; X int x_pos, y_pos; X WINDOW *inwin; X X initscr(); X clear(); X refresh(); X X /* set up interupt handler */ X signal(SIGINT, clean_up); X X /* set up input window */ X inwin = newwin(8, COLS, 3, 0); X if (inwin == (WINDOW *) NULL) X clean_up(); X X /* print out header */ X box(inwin, '|', '-'); X for (n = 0; n < 4; n++) X mvwaddstr(inwin, n + 1, COLS / 2 - strlen(header[n]) / 2, header[n]); X mvwaddstr(inwin, 6, 15, "Enter input --> "); X /* get the prompt positions so we can return at later time */ X getyx(inwin, y_pos, x_pos); X wrefresh(inwin); X X /* now get string */ X do X { X /* clear last input */ X wmove(inwin, y_pos, x_pos); X wclrtoeol(inwin); X box(inwin, '|', '-'); X wrefresh(inwin); X X /* X * get string. NO_RET=0 and RET=1 are defined in X * "my_wgetstr.h" X */ X n = my_wgetstr(inwin, buffer, sizeof(buffer), NO_RET); X X /* print out the result of my_wgetstr */ X move(15, 15); X clrtoeol(); X mvprintw(15, 15, "Received %d chars -- \"%s\"", n, buffer); X refresh(); X X /* move back to the input prompt */ X wmove(inwin, y_pos, x_pos); X wrefresh(inwin); X } X while (n != 0); /* while input is not empty */ X X name = getenv("NAME"); X if (name == (char *) NULL) /* use login if NAME is not set */ X name = getlogin(); X /* say good bye */ X move(15, 15); X clrtoeol(); X sprintf(ender, "GOOD BYE, \"%s\"", name); X mvprintw(15, COLS / 2 - strlen(ender) / 2, "%s", ender); X X /* move to last line ... looks cleaner this way */ X move(LINES - 1, 0); X refresh(); X clean_up(); X} X Xclean_up() X{ X endwin(); X exit(); X} SHAR_EOF if test 2271 -ne "`wc -c < 'example.c'`" then echo shar: error transmitting "'example.c'" '(should have been 2271 characters)' fi fi # end of overwriting check echo shar: extracting "'makefile'" '(128 characters)' if test -f 'makefile' then echo shar: will not over-write existing file "'makefile'" else sed 's/^ X//' << \SHAR_EOF > 'makefile' XLIBS= -lcurses -ltermcap XOBJS= example.o my_wgetstr.o XCFLAGS= -s -O X Xexample: $(OBJS) X cc $(CFLAGS) -o example $(OBJS) $(LIBS) SHAR_EOF if test 128 -ne "`wc -c < 'makefile'`" then echo shar: error transmitting "'makefile'" '(should have been 128 characters)' fi fi # end of overwriting check echo shar: extracting "'my_wgetstr.c'" '(3993 characters)' if test -f 'my_wgetstr.c' then echo shar: will not over-write existing file "'my_wgetstr.c'" else sed 's/^ X//' << \SHAR_EOF > 'my_wgetstr.c' X/* X * A possible replacement for curses' wgetstr(). Allows X * line editing as in csh. X * Recognizes the erase, kill chars, word deleting. X * X * By Hung Le (mott@ucscb.ucsc.edu ...!ucbvax!ucscc!ucscb!mott) X * History: X * 01/18/89 - Initial version X * 03/20/89 - Add control-w to delete word X * 05/17/89 - add option to return immediately or to bell() X * when buffer is full. X * X * Release to Public Domain X */ X#include <curses.h> X#include <sys/ioctl.h> X#include <sgtty.h> X X#define STD_INPUT 0 /* standard input */ X#define NEWLINE '\n' X#define SPACE ' ' X/* default for erase and kill characters */ X#define ERASE '\010' X#define KILL '\025' X#define WORD '\027' X X/* You bugger !!! you did something wrong */ X#define bell() fprintf(stderr,"%c", '\007') X X/* X * my_wgetstr(WINDOW *win, char *str, int size, int ret) X * win: the concerned window X * str: buffer holding input X * size: (size -1) is the maximum chars to get X * ret: flag indicating what to do when (size -1) is reached X * 0: ring bell() X * 1: returns X * two macros are defined in "my_wgetstr.h" as RET=1 and NO_RET=0 X * X * works same as wgetstr() in curses but allows editing. X * Recognizes the erase character and the kill character and X * WORD as the word deleting char. X * Will try to get the erase and kill char from the terminal setting. X * If failed, will use the default ERASE and KILL definitions. X * Word char is set to WORD. X * X * DOES NOT check for illegal scrolling. X * Returns X * . when received a new line character X * . if ( (strlen(str) == (size - 1)) and (ret) ) X * X * str[size - 1] must be set to '\0' to end the string properly X * so my_wgetstr(errwin, str, 8) will get at most 7 characters. X * X * Returned value is the number of chars read. X */ X Xmy_wgetstr(win, str, size, ret) XWINDOW *win; Xchar *str; Xint size; Xint ret; X{ X struct sgttyb ttyb; X char erase_char, kill_char; X register int x_pos, y_pos, index, in; X X if (ioctl(STD_INPUT, TIOCGETP, &ttyb) == -1) X { X /* X * failed to get terminal setting. Let's use the default X * ERASE and KILL X */ X erase_char = ERASE; X kill_char = KILL; X } X else X { X erase_char = ttyb.sg_erase; X kill_char = ttyb.sg_kill; X } X X /* X * since we are going to set noecho() and crmode() let's be safe and X * save the current tty X */ X savetty(); X noecho(); X crmode(); X X /* get current position */ X getyx(win, y_pos, x_pos); X /* intializing */ X index = 0; X str[index] = '\0'; X X /* while input char is not NEWLINE */ X while ((in = getch() & 0177) != NEWLINE) X { X /* if buffer is full (size -1) */ X if (index >= size - 1) X if (ret)/* return flag set, return immediately */ X break; X else /* allows editing chars to pass through */ X if ((in != erase_char) && (in != kill_char) && (in != WORD)) X { X /* warns user that buffer is full */ X bell(); X continue; X } X X if (in == erase_char) /* ERASING */ X { X if (index > 0) X { X mvwaddch(win, y_pos, --x_pos, SPACE); X str[--index] = SPACE; X wmove(win, y_pos, x_pos); X } X else X bell(); X } X else X if (in == kill_char) /* KILLING */ X { X if (index > 0) X while (index > 0) X { X mvwaddch(win, y_pos, --x_pos, SPACE); X str[--index] = SPACE; X wmove(win, y_pos, x_pos); X } X else X bell(); X } X else X if (in == WORD) /* WORD DELETING */ X { X if (index > 0) X { X /* throw away all spaces */ X while ((index > 0) && (str[index - 1] == SPACE)) X { X mvwaddch(win, y_pos, --x_pos, SPACE); X str[--index] = SPACE; X wmove(win, y_pos, x_pos); X } X /* move back until see another space */ X while ((index > 0) && (str[index - 1] != SPACE)) X { X mvwaddch(win, y_pos, --x_pos, SPACE); X str[--index] = SPACE; X wmove(win, y_pos, x_pos); X } X } X else X bell(); X } X else X { X mvwaddch(win, y_pos, x_pos++, in); X str[index++] = in; X } X /* show result */ X wrefresh(win); X } X /* ends the string properly */ X str[index] = '\0'; X /* restore the tty */ X resetty(); X /* returns number of chars read */ X return (index); X} SHAR_EOF if test 3993 -ne "`wc -c < 'my_wgetstr.c'`" then echo shar: error transmitting "'my_wgetstr.c'" '(should have been 3993 characters)' fi fi # end of overwriting check echo shar: extracting "'my_wgetstr.h'" '(400 characters)' if test -f 'my_wgetstr.h' then echo shar: will not over-write existing file "'my_wgetstr.h'" else sed 's/^ X//' << \SHAR_EOF > 'my_wgetstr.h' X/* X * A possible replacement for curses' wgetstr(). Allows X * limited editing. Recognizes the erase and kill chars. X * X * By Hung Le (mott@ucscb.ucsc.edu ...!ucbvax!ucscc!ucscb!mott) X * History: X * 05/18/89 - Initial version X * X * Release to Public Domain X */ X X/* following the curses's convention */ X#define my_getstr(str,size,ret) my_wgetstr(stdscr,str,size,ret) X#define RET 1 X#define NO_RET 0 X SHAR_EOF if test 400 -ne "`wc -c < 'my_wgetstr.h'`" then echo shar: error transmitting "'my_wgetstr.h'" '(should have been 400 characters)' fi fi # end of overwriting check # End of shell archive exit 0