v07i015: my_wgetstr(); wgetstr() with line editing
Brandon S. Allbery - comp.sources.misc
allbery at uunet.UU.NET
Sun Jun 4 11:52:25 AEST 1989
Posting-number: Volume 7, Issue 15
Submitted-by: mott at 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 at ucscb.ucsc.edu ...!ucbvax!ucscc!ucscb!mott
mott at 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 at 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 at 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 at 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 at 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
More information about the Comp.sources.misc
mailing list