Path: seismo!harvard!talcott!panda!sources-request From: sources-request@panda.UUCP Newsgroups: mod.sources Subject: libc_term - datum entry using curses Message-ID: <1368@panda.UUCP> Date: 5 Feb 86 00:04:42 GMT Sender: jpn@panda.UUCP Lines: 1593 Approved: jpn@panda.UUCP Mod.sources: Volume 3, Issue 101 Submitted by: "George W. Sherouse" Here is a library of bullet-proof datum-entry routines that has gotten a fair bit of use here and elsewhere. It was posted to net.sources quite awhile ago. - George -------------------------- cut here ------------------------ #! /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 # Makefile # c_term.l # c_term.h # center.c # examp.c # get_bool.c # get_erase.c # get_float.c # get_hosp_num.c # get_int.c # get_string.c # init_term.c # pick_one.c # This archive created: Sat Jan 25 11:54:18 1986 export PATH; PATH=/bin:$PATH echo shar: extracting "'README'" '(777 characters)' if test -f 'README' then echo shar: will not over-write existing file "'README'" else sed 's/^ X//' << \SHAR_AND_ENJOY > 'README' XThis directory contains the source for a library (libc_term) of Xbullet-proof datum-entry routines that sit on top of curses. Another Xversion exists which uses termcap directly (libterm). X XThe code is rather a mess and in some cases rather inefficient. That Xis a statement not an apology. This was some of my first C code and Xhas been used extensively here and elsewhere with *NO* bug reports. XThis same code was posted to net.sources about 18 months ago and a Xtrickle of requests has continued since then. If it ain't broke don't Xfix it. X XPermission is granted to copy and redistribute this code as long as no Xmoney changes hands and this notice and the authorship notes remain Xintact. Let me know if you find/fix any bugs. Enjoy. X X- George X X SHAR_AND_ENJOY if test 777 -ne "`wc -c < 'README'`" then echo shar: error transmitting "'README'" '(should have been 777 characters)' fi fi # end of overwriting check echo shar: extracting "'Makefile'" '(956 characters)' if test -f 'Makefile' then echo shar: will not over-write existing file "'Makefile'" else sed 's/^ X//' << \SHAR_AND_ENJOY > 'Makefile' XCFLAGS = -O XLIBDIR = /usr/local/lib XMANDIR = /usr/man/manl XINCDIR = /usr/include X XOBJS = init_term.o get_erase.o get_float.o get_int.o\ X get_bool.o get_hosp_num.o get_string.o pick_one.o\ X center.o X Xlibc_term.a: $(OBJS) Makefile X ar rcv libc_term.a $(OBJS) X ranlib libc_term.a X Xinit_term.o: init_term.c c_term.h Makefile Xget_erase.o: get_erase.c c_term.h Makefile Xget_float.o: get_float.c c_term.h Makefile Xget_int.o: get_int.c c_term.h Makefile Xget_bool.o: get_bool.c c_term.h Makefile Xget_hosp_num.o: get_hosp_num.c c_term.h Makefile Xget_string.o: get_string.c c_term.h Makefile Xpick_one.o: pick_one.c c_term.h Makefile Xcenter.o: center.c c_term.h Makefile X Xexamp: examp.c c_term.h /usr/local/lib/libc_term.a Makefile X cc $(CFLAGS) -o examp examp.c -lc_term -lcurses -ltermcap X Xinstall: libc_term.a X mv libc_term.a $(LIBDIR) X ranlib $(LIBDIR)/libc_term.a X cp c_term.h $(INCDIR) X Xinstall_man: c_term.l X cp c_term.l $(MANDIR) X Xclean: X rm -f *.o a.out core SHAR_AND_ENJOY if test 956 -ne "`wc -c < 'Makefile'`" then echo shar: error transmitting "'Makefile'" '(should have been 956 characters)' fi fi # end of overwriting check echo shar: extracting "'c_term.l'" '(3585 characters)' if test -f 'c_term.l' then echo shar: will not over-write existing file "'c_term.l'" else sed 's/^ X//' << \SHAR_AND_ENJOY > 'c_term.l' X.TH C_TERM L "Radiation Oncology, NCMH" X.UC 4 X.SH NAME Xc_term \- "crash-proof" datum-entry routines for curses(3x) X.SH SYNOPSIS X#include X.br X#include X.br X.B cc X[ flags ] files X.B \-lc_term \-lcurses \-ltermcap X[ libraries ] X.SH DESCRIPTION XThese routines look after datum-entry through stdscr for the basic datum Xtypes. XAn initial call to X.I init_term Xinitializes the curses package by calling X.I initscr, raw, and noecho, Xand initializes X.I c_term Xby fetching the terminal's erase character. XIn typical use, the calling program would paint a screen Xand place the cursor at the beginning of a datum field Xusing X.I curses(3x) Xand would then call the appropriate X.I c_term Xroutine to enter or edit that datum. XThe field is highlighted using standout mode and the default value, if any, Xis displayed. XThe user may then enter a new value of the datum under strict field size Xenforcement or accept the default. XAcceptance of the displayed value is indicated by a RETURN. XThe default value can be retrieved by ^X. XThe program can be aborted by a character which is defined at installation of Xthe library. XIf ABORT_CHAR is not defined, no abort is possible. XWhen the value is accepted, the field is rewritten in normal mode and with the Xnew value of the datum, and the cursor is left at the end of the field. X XExceptions to the above are X.I get_bool Xfor which valid inputs are n, N, y, Y, SPACE, and RETURN, for Xno, yes, toggle, and accept respectively, Xand X.I pick_one Xwhich understands ^ for previous value, SPACE for next value, and RETURN Xfor accept. X XThe user is still responsible for the X.I endwin() Xbefore exiting. X.SH SEE ALSO Xcurses(3x) X.SH AUTHOR X.nf XGeorge W. Sherouse XRadiation Oncology XNorth Carolina Memorial Hospital XUniversity of North Carolina, Chapel Hill X.SH FUNCTIONS X.nf XInitialize curses and c_term. X void init_term(); X XGet a floating point number. Imagine %(field_width).(places)f Xin a printf. X float get_float(default, field_width, places); X float default; X int field_width; X int places; X XGet an integer. X int get_int(default, field_width); X int default; X int field_width; X XGet a boolean. X int get_bool(default); X int default; X XGet a hospital number in the format 00-00-00. X void get_hosp_num(hosp_num); X char *hosp_num X XGet a string. String should be at least field_size + 1 long Xto accomodate the appended null. Null_ok is a boolean which Xdeclares whether or not a string of length zero is acceptable. X void get_string(string, field_size, null_ok); X char *string; X int field_size; X int null_ok; X XPick one string from a list of strings. X int pick_one(list, choice_count); X char **list; X int choice_count; X XPrint string centered on line. Mode is a boolean which requests Xstandout mode if TRUE. X void center(line, string, mode); X int line; X char *string; X int mode; X.SH BUGS XMany sorts of stupidity are not checked for. XThese include but are not limited to string longer than COLS in X.I center, Xfractional part longer than field_size in X.I get_float, Xand 0 or negative field_size anywhere. X X.I Get_float Xdoes not support scientific notation. XIt also does not let you back up over the decimal point once it has placed Xit. XThis is no great hardship since you can always ^X to restart. X XStandout mode as implemented in X.I curses(3x) Xis not reliable. XTry it on a terminal with magic cookies. X XSome of the code is a little ugly, having been hacked unmercifully through many Xrevisions. XIn particular, this X.I curses Xcompatible version is actually a hacked subset of a version which Xtalks to X.I termcap(3x) Xdirectly. XIt does seem to work, though. SHAR_AND_ENJOY if test 3585 -ne "`wc -c < 'c_term.l'`" then echo shar: error transmitting "'c_term.l'" '(should have been 3585 characters)' fi fi # end of overwriting check echo shar: extracting "'c_term.h'" '(203 characters)' if test -f 'c_term.h' then echo shar: will not over-write existing file "'c_term.h'" else sed 's/^ X//' << \SHAR_AND_ENJOY > 'c_term.h' X#define ABORT_CHAR ('\03') X Xvoid init_term(); Xchar get_erase(); Xfloat get_float(); Xint get_int(); Xint get_bool(); Xvoid get_hosp_num(); Xvoid get_string(); Xint pick_one(); Xvoid center(); X Xchar erase_char; SHAR_AND_ENJOY if test 203 -ne "`wc -c < 'c_term.h'`" then echo shar: error transmitting "'c_term.h'" '(should have been 203 characters)' fi fi # end of overwriting check echo shar: extracting "'center.c'" '(1482 characters)' if test -f 'center.c' then echo shar: will not over-write existing file "'center.c'" else sed 's/^ X//' << \SHAR_AND_ENJOY > 'center.c' X#include X#include X#include "c_term.h" X Xvoid center(line, string, mode) Xint line; Xchar *string; Xint mode; X X/* X --------------------------------------------------------------------------- X X Last revision - X 6 January 1985 - GWS X Change to use curses X X 2 April 1984 - GWS X X X NAME X center - center string in sceen X X SYNOPSIS X void center(line, string, mode) X int line; X char *string; X int mode; X X DESCRIPTION X This routine uses the curses(3x) routines to center and X optionally emphasize a string. 'Line' is the terminal line X number on which the string is to be placed, numbered starting X with 0. 'Mode' takes one of three values: X 0 - no control characters sent X 1 - stand-out mode turned on before and off after 'string' X 2 - stand-out mode turned on before and off after 'string' X A call to init_term must be made before the first call to center. X X SEE ALSO X curses(3x), init_term X X DIAGNOSTICS X none X X BUGS X does not check for string too long to fit on one line X X AUTHOR X George W. Sherouse X 31 March 1984 X X --------------------------------------------------------------------------- X*/ X X{ X int col; X X int strlen(); X X col = (COLS - strlen(string)) / 2 - 1; X switch (mode) X { X case 0: X break; X case 1: X case 2: X standout(); X break; X } X mvprintw(line, col, string); X switch (mode) X { X case 0: X break; X case 1: X case 2: X standend(); X break; X } X refresh(); X return; X} SHAR_AND_ENJOY if test 1482 -ne "`wc -c < 'center.c'`" then echo shar: error transmitting "'center.c'" '(should have been 1482 characters)' fi fi # end of overwriting check echo shar: extracting "'examp.c'" '(1557 characters)' if test -f 'examp.c' then echo shar: will not over-write existing file "'examp.c'" else sed 's/^ X//' << \SHAR_AND_ENJOY > 'examp.c' X#include X#include "c_term.h" X/* X X*/ X Xmain() X X{ X int num1, num2; X float fnum1, fnum2; X char HospNum[9]; X char text[20]; X static char *table[] = X { X "Number one", X "Number two", X "And even yet another" X }; X X X init_term(); X clear(); X X printw("Here are your choices -->"); X num1 = pick_one(table, 3); X printw("<--\nNumber %d was chosen\n", num1); X X move(2, 0); X printw("Here are your choices -->"); X num1 = pick_one(table, 1); X printw("<--\nNumber %d was chosen\n", num1); X X move(4, 0); X printw("Enter a string -->"); X get_string(text, 15, 0); X printw("<--\nString is %s\n", text); X X move(6, 0); X printw("yes or no ? -->"); X num1 = get_bool(1); X printw(","); X num2 = get_bool(num1); X printw("<---\n"); X printw("Booleans are %d, %d\n", num1, num2); X X move(8, 0); X printw("Enter a number --->"); X num1 = get_int(50, 4); X printw(","); X num2 = get_int(num1, 6); X printw("<---\n"); X printw("Numbers were %d, %d\n", num1, num2); X X move(10, 0); X printw("Enter a number --->"); X fnum1 = get_float(50.0, 8, 5); X printw(","); X fnum2 = get_float(fnum1, 6, 2); X printw("<---\n"); X printw("Numbers were %f, %f\n", fnum1, fnum2); X X move(12, 0); X printw("Enter hospital number --->"); X get_hosp_num(HospNum); X printw("<---\n"); X printw("Number is %s\n", HospNum); X X center(20, "This should be centered in line 20", 0); X center(21, "This should stand out in line 21", 1); X move(LINES - 1, 0); X refresh(); X endwin(); X X} SHAR_AND_ENJOY if test 1557 -ne "`wc -c < 'examp.c'`" then echo shar: error transmitting "'examp.c'" '(should have been 1557 characters)' fi fi # end of overwriting check echo shar: extracting "'get_bool.c'" '(1643 characters)' if test -f 'get_bool.c' then echo shar: will not over-write existing file "'get_bool.c'" else sed 's/^ X//' << \SHAR_AND_ENJOY > 'get_bool.c' X#include X#include X#include "c_term.h" X Xint get_bool(Default) Xint Default; X X/* X --------------------------------------------------------------------------- X X Last revision - X 6 January 1985 - GWS X Change to use curses X X 16 November 1984 - GWS X Ignore XON, XOFF X X 11 April 1984 - GWS X X X NAME X get_bool - "crash-proof" routine for terminal input of boolean X X SYNOPSIS X int get_bool(Default) X int Default; X X DESCRIPTION X This routine prompts and nudges the user through entry of a X boolean value. X X SEE ALSO X X X DIAGNOSTICS X none X X BUGS X none known X X AUTHOR X George W. Sherouse X 11 April 1984 X X --------------------------------------------------------------------------- X*/ X X{ X int c; X int val, X where_y, X where_x; X X getyx(stdscr, where_y, where_x); X standout(); X X val = Default; X while (1) X { X if (val) X mvprintw(where_y, where_x, "yes"); X else X mvprintw(where_y, where_x, "no "); X refresh(); X X switch (c = (getch() & 0177)) X { X#ifdef ABORT_CHAR X case ABORT_CHAR: X clear(); X standend(); X mvprintw(0, 0, "Program aborted at your request..."); X move(LINES - 1, 0); X refresh(); X endwin(); X exit(0); X break; X#endif ABORT_CHAR X X case '\015': X standend(); X if (val) X mvprintw(where_y, where_x, "yes"); X else X mvprintw(where_y, where_x, "no "); X refresh(); X return(val); X break; X case ' ': X val = !val; X break; X case 'y': X case 'Y': X val = 1; X break; X case 'n': X case 'N': X val = 0; X break; X case '\021': X case '\023': X break; X default: X fprintf(stderr, "%c", '\007'); X } X } X} SHAR_AND_ENJOY if test 1643 -ne "`wc -c < 'get_bool.c'`" then echo shar: error transmitting "'get_bool.c'" '(should have been 1643 characters)' fi fi # end of overwriting check echo shar: extracting "'get_erase.c'" '(824 characters)' if test -f 'get_erase.c' then echo shar: will not over-write existing file "'get_erase.c'" else sed 's/^ X//' << \SHAR_AND_ENJOY > 'get_erase.c' X X#include X#include X#include X#include "c_term.h" X Xchar get_erase() X/* X --------------------------------------------------------------------------- X X Last revision - X 6 January 1985 - GWS X X X NAME X get_erase - get erase character for terminal X X SYNOPSIS X char get_erase() X X DESCRIPTION X The return character is the terminal's erase character. X X SEE ALSO X X X DIAGNOSTICS X Will exit(1) on any error. X X BUGS X none known X X AUTHOR X George W. Sherouse X 3 January 1985 X X --------------------------------------------------------------------------- X*/ X X{ X struct sgttyb params; X int ret; X int ioctl(); X X ret = ioctl(0, TIOCGETP, ¶ms); X if (ret == -1) X { X fprintf(stderr, "ioctl fail\n"); X perror("get_erase"); X exit(1); X } X X return(params.sg_erase); X} SHAR_AND_ENJOY if test 824 -ne "`wc -c < 'get_erase.c'`" then echo shar: error transmitting "'get_erase.c'" '(should have been 824 characters)' fi fi # end of overwriting check echo shar: extracting "'get_float.c'" '(4515 characters)' if test -f 'get_float.c' then echo shar: will not over-write existing file "'get_float.c'" else sed 's/^ X//' << \SHAR_AND_ENJOY > 'get_float.c' X#include X#include X#include X#include "c_term.h" X Xfloat get_float(Default, field_width, places) Xfloat Default; Xint field_width, places; X X/* X --------------------------------------------------------------------------- X X Last revision - X 6 January 1985 - GWS X Make it use curses X X 16 November 1984 - GWS X Ignore XON, XOFF X X 11 April 1984 - GWS X X X NAME X get_float - "crash-proof" float from keyboard routine X X SYNOPSIS X float get_float(Default, field_width, places) X float Default; X int field_width, places; X X DESCRIPTION X On a good day this routine will get a real value from the X keyboard and return it safely. The terminal is placed in raw X mode and most non-digit values are beeped at and discarded. Entry X is terminated by filling the field or by CR. CR as first character X assumes Default. ^X restarts. X X SEE ALSO X X X DIAGNOSTICS X none - cannot fail :-) X X BUGS X Doesn't check for silly things like Default too big to fit in X field_width, etc. Watch out for that minus sign!! X X Exponential notation is not supported. X X This version does not let you erase over the decimal point if X the integer part of the field is already full. This is not a X terrible hardship because you are free to ^X and start over, X but it really should be fixed. X X AUTHOR X George W. Sherouse X 9 April 1984 X X --------------------------------------------------------------------------- X*/ X X{ X int c; X float val; X int loop; X char line_buff[20]; X char Format[80]; X char pad; X int point, frac_count; X int count; X int int_part; X int where_x, X where_y, X x, X y; X X void f_clean_up(); X X pad = ' '; X point = 0; X frac_count = 0 ; X X getyx(stdscr, where_y, where_x); X standout(); X X for (loop = 0; loop < field_width; loop++) X printw(" "); X X move(where_y, where_x); X refresh(); X X sprintf(Format, "%%%d.%df", field_width, places); X printw(Format, Default); X move(where_y, where_x); X refresh(); X for (loop = 0; loop <= field_width; loop++) X line_buff[loop] = 0; X X count = 0; X int_part = field_width - places - 1; X while (1) X { X if (!point && count == int_part) X { X printw("."); X line_buff[count++] = '.'; X point++; X continue; X } X refresh(); X X c = (getch() & 0x7f); X switch(c) X { X#ifdef ABORT_CHAR X case ABORT_CHAR: X clear(); X standend(); X mvprintw(0, 0, "Program aborted at your request..."); X move(LINES -1 , 0); X refresh(); X endwin(); X exit(1); X break; X#endif ABORT_CHAR X X case '\r': X if (count && line_buff[count - 1] != '-') X { X sscanf(line_buff, "%f", &val); X f_clean_up(where_y, where_x, Format, val); X return(val); X } X else X { X f_clean_up(where_y, where_x, Format, Default); X return(Default); X } X break; X case '\030': X move(where_y, where_x); X for (loop = 0; loop < field_width; loop++) X line_buff[loop] = 0; X count = frac_count = point = 0; X printw(Format, Default); X move(where_y, where_x); X break; X case '.': X if (!point) X { X if (!count) X { X for (loop = 0; loop < field_width; loop++) X printw("%c", pad); X move(where_y, where_x); X for (loop = 0; loop < field_width; loop++) X line_buff[loop] = 0; X } X printw("."); X line_buff[count++] = '.'; X point++; X break; X } X case '\021': X case '\023': X break; X default: X if (c == erase_char && count) X { X getyx(stdscr, y, x); X move(y, x - 1); X printw("%c", pad); X move(y, x - 1); X if (point) X { X if (frac_count) X frac_count--; X else X point--; X } X line_buff[--count] = 0; X break; X } X X if (!count && c == '-') X { X for (loop = 0; loop < field_width; loop++) X printw("%c", pad); X move(where_y, where_x); X for (loop = 0; loop < field_width; loop++) X line_buff[loop] = 0; X X line_buff[count++] = (char) c; X printw("-"); X break; X } X X if (isdigit(c) && count < field_width && frac_count < places) X { X if (!count) X { X for (loop = 0; loop < field_width; loop++) X printw("%c", pad); X move(where_y, where_x); X for (loop = 0; loop < field_width; loop++) X line_buff[loop] = 0; X } X printw("%c", c); X line_buff[count++] = (char) c; X if (point) X frac_count++; X } X else X fprintf(stderr, "%c", '\007'); X } X } X} X Xvoid f_clean_up(where_y, where_x, Format, val) Xint where_y, where_x; Xchar *Format; Xfloat val; X X{ X int loop; X X standend(); X move(where_y, where_x); X printw(Format, val); X X refresh(); X} SHAR_AND_ENJOY if test 4515 -ne "`wc -c < 'get_float.c'`" then echo shar: error transmitting "'get_float.c'" '(should have been 4515 characters)' fi fi # end of overwriting check echo shar: extracting "'get_hosp_num.c'" '(2331 characters)' if test -f 'get_hosp_num.c' then echo shar: will not over-write existing file "'get_hosp_num.c'" else sed 's/^ X//' << \SHAR_AND_ENJOY > 'get_hosp_num.c' X#include X#include X#include "c_term.h" X Xvoid get_hosp_num (HospNum) Xchar *HospNum; X X/* X --------------------------------------------------------------------------- X X Last revision - X 6 January 1985 - GWS X Change it to use curses X X 16 November 1984 - GWS X Ignore XON, XOFF X X 11 April 1984 - GWS X X X NAME X get_hosp_num - "crash-proof" routine for terminal input of ##-##-## X X SYNOPSIS X void get_hosp_num(HospNum) X char *HospNum; X X DESCRIPTION X This routine prompts and nudges the user through entry of a X hospital number in the proper format. X X SEE ALSO X X X DIAGNOSTICS X none X X BUGS X Doesn't do any validity checking on the number, only the format. X X AUTHOR X George W. Sherouse X 9 April 1984 X X --------------------------------------------------------------------------- X*/ X X{ X int c; X int count, X where_y, X where_x, X x, X y; X X getyx(stdscr, where_y, where_x); X standout(); X X printw(" - - "); X move(where_y, where_x); X refresh(); X X count = 0; X while (1) X { X switch (count) X { X case 2: X case 5: X printw("-"); X HospNum[count++] = '-'; X break; X default: X switch (c = (getchar() & 0177)) X { X#ifdef ABORT_CHAR X case ABORT_CHAR: X clear(); X standend(); X mvprintw(0, 0, "Program aborted at your request..."); X move(LINES - 1, 0); X refresh(); X endwin(); X exit(0); X break; X#endif ABORT_CHAR X X case '\015': X if (count == 8) X { X HospNum[8] = (char) 0; X standend(); X mvprintw(where_y, where_x, HospNum); X refresh(); X return; X } X else X { X fprintf(stderr, "%c", '\007'); X break; X } X case 030: X mvprintw(where_y, where_x, " - - "); X move(where_y, where_x); X count = 0; X break; X case '\021': X case '\023': X break; X default: X if (c == erase_char && count) X { X switch (count) X { X case 3: X case 6: X getyx(stdscr, y, x); X move(y, x - 1); X count--; X case 1: X case 2: X case 4: X case 5: X case 7: X case 8: X getyx(stdscr, y, x); X mvprintw(y, x - 1, " "); X move(y, x - 1); X HospNum[--count] = 0; X break; X } X break; X } X X if (isdigit(c) && count < 8) X { X printw("%c", c); X HospNum[count++] = (char) c; X } X else X fprintf(stderr, "%c", '\007'); X } X } X refresh(); X } X} SHAR_AND_ENJOY if test 2331 -ne "`wc -c < 'get_hosp_num.c'`" then echo shar: error transmitting "'get_hosp_num.c'" '(should have been 2331 characters)' fi fi # end of overwriting check echo shar: extracting "'get_int.c'" '(3386 characters)' if test -f 'get_int.c' then echo shar: will not over-write existing file "'get_int.c'" else sed 's/^ X//' << \SHAR_AND_ENJOY > 'get_int.c' X#include X#include X#include "c_term.h" X Xint get_int(Default, field_width) Xint Default, field_width; X X/* X --------------------------------------------------------------------------- X X Last revision - X 6 January 1985 - GWS X Change to use curses X X 16 November 1984 - GWS X Ignore XON, XOFF X X 11 April 1984 - GWS X X X NAME X get_int - "crash-proof" integer from keyboard routine X X SYNOPSIS X int get_int(Default, field_width) X int Default, field_width; X X DESCRIPTION X On a good day this routine will get an integer value from the X keyboard and return it safely. The terminal is placed in raw X mode and most non-digit values are beeped at and discarded. Entry X is terminated by filling the field or by CR. CR as first character X assumes Default. ^X restarts. X X SEE ALSO X X DIAGNOSTICS X none - cannot fail :-) X X BUGS X Doesn't check for silly things like Default too big to fit in X field_width, etc. Let's be particularly careful out there. X X AUTHOR X George W. Sherouse X 6 April 1984 X X --------------------------------------------------------------------------- X*/ X X{ X int c, val; X int loop; X char line_buff[20]; X char Format[80]; X char pad; X int count; X int where_x, X where_y, X x, X y; X X void clean_up(); X X pad = ' '; X getyx(stdscr, where_y, where_x); X standout(); X X for (loop = 0; loop < field_width; loop++) X printw(" "); X X sprintf(Format, "%%%dd", field_width); X mvprintw(where_y, where_x, Format, Default); X move(where_y, where_x); X refresh(); X for (loop = 0; loop <= field_width; loop++) X line_buff[loop] = 0; X X count = 0; X while (1) X { X switch (c = (getch() & 0177)) X { X#ifdef ABORT_CHAR X case ABORT_CHAR: X clear(); X standend(); X mvprintw(0, 0, "Program aborted at your request..."); X move(LINES - 1, 0); X refresh(); X endwin(); X exit(0); X break; X#endif ABORT_CHAR X X case '\015': X if (count && line_buff[count - 1] != '-') X { X sscanf(line_buff, "%d", &val); X clean_up(where_y, where_x, Format, val); X return(val); X } X else X { X clean_up(where_y, where_x, Format, Default); X return(Default); X } X break; X case 030: X for (loop = 0; loop < field_width; loop++) X line_buff[loop] = 0; X count = 0; X mvprintw(where_y, where_x, Format, Default); X move(where_y, where_x); X break; X case '\021': X case '\023': X break; X default: X if (c == erase_char && count) X { X getyx(stdscr, y, x); X mvprintw(y, x - 1, "%c", pad); X move(y, x - 1); X line_buff[--count] = 0; X break; X } X X if (!count && c == '-') X { X for (loop = 0; loop < field_width; loop++) X printw("%c", pad); X move(where_y, where_x); X for (loop = 0; loop < field_width; loop++) X line_buff[loop] = 0; X X line_buff[count++] = (char) c; X printw("-"); X break; X } X X if (isdigit(c) && count < field_width) X { X if (!count) X { X for (loop = 0; loop < field_width; loop++) X printw("%c", pad); X move(where_y, where_x); X for (loop = 0; loop < field_width; loop++) X line_buff[loop] = 0; X } X printw("%c", c); X line_buff[count++] = (char) c; X } X else X fprintf(stderr, "%c", '\007'); X } X refresh(); X } X} X Xvoid clean_up(where_y, where_x, Format, val) Xint where_y, where_x; Xchar *Format; Xint val; X X{ X int loop; X X standend(); X mvprintw(where_y, where_x, Format, val); X refresh(); X} SHAR_AND_ENJOY if test 3386 -ne "`wc -c < 'get_int.c'`" then echo shar: error transmitting "'get_int.c'" '(should have been 3386 characters)' fi fi # end of overwriting check echo shar: extracting "'get_string.c'" '(2357 characters)' if test -f 'get_string.c' then echo shar: will not over-write existing file "'get_string.c'" else sed 's/^ X//' << \SHAR_AND_ENJOY > 'get_string.c' X#include X#include X#include "c_term.h" X Xvoid get_string(string, size, nullOK) Xchar *string; Xint size; Xint nullOK; X X/* X --------------------------------------------------------------------------- X X Last revision - X 6 January 1985 - GWS X Change to use curses X X 16 November 1984 - GWS X Ignore XON, XOFF X X 11 April 1984 - GWS X X X NAME X get_string - "crash-proof" routine for terminal input of string X X SYNOPSIS X void get_string(string, size, nullOK) X char *string; X int size; X int nullOK; X X DESCRIPTION X This routine prompts and nudges the user through entry of a X character string. 'Size' is the number of characters in'string'. X 'String' should therefore be dimensioned to size + 1. X 'NullOK' is a boolean that tells us whether a null string is X acceptable. X X SEE ALSO X X X DIAGNOSTICS X none X X BUGS X none known X X AUTHOR X George W. Sherouse X 11 April 1984 X X --------------------------------------------------------------------------- X*/ X X{ X int c; X int loop; X int count, X where_x, X where_y, X x, X y; X char Format[30]; X X standout(); X getyx(stdscr, where_y, where_x); X X for (loop = 0; loop < size; loop++) X { X printw(" "); X string[loop] = (char) 0; X } X string[size] = (char) 0; X move(where_y, where_x); X refresh(); X X count = 0; X while (1) X { X switch (c = (getch() & 0177)) X { X#ifdef ABORT_CHAR X case ABORT_CHAR: X clear(); X standend(); X mvprintw(0, 0, "Program aborted at your request..."); X move(LINES - 1, 0); X refresh(); X endwin(); X exit(0); X break; X#endif ABORT_CHAR X X case '\015': X if (count || nullOK) X { X standend(); X sprintf(Format, "%%-%ds", size); X mvprintw(where_y, where_x, Format, string); X refresh(); X return; X } X else X { X fprintf(stderr, "%c", '\007'); X break; X } X case '\030': X while (count) X { X string[--count] = (char) 0; X getyx(stdscr, y, x); X mvprintw(y, x-1, " "); X move(y, x - 1); X } X break; X case '\021': X case '\023': X break; X default: X if (count && c == erase_char) X { X getyx(stdscr, y, x); X mvprintw(y, x-1, " "); X move(y, x - 1); X string[--count] = (char) 0; X break; X } X X if (isprint(c) && count < size) X { X printw("%c", c); X string[count++] = c; X break; X } X X fprintf(stderr, "%c", '\007'); X } X refresh(); X } X} SHAR_AND_ENJOY if test 2357 -ne "`wc -c < 'get_string.c'`" then echo shar: error transmitting "'get_string.c'" '(should have been 2357 characters)' fi fi # end of overwriting check echo shar: extracting "'init_term.c'" '(690 characters)' if test -f 'init_term.c' then echo shar: will not over-write existing file "'init_term.c'" else sed 's/^ X//' << \SHAR_AND_ENJOY > 'init_term.c' X#include X#include "c_term.h" X Xvoid init_term() X/* X --------------------------------------------------------------------------- X X Last revision - X 6 January 1985 - GWS X X X NAME X init_term - initialize curses and c_term X X SYNOPSIS X void init_term() X X DESCRIPTION X This routine must be called before use of the c_term X idiot-proof input library. It includes a call to initscr X to initialize curses. X X DIAGNOSTICS X X X FILES X X X SEE ALSO X curses(3X) X X BUGS X X X AUTHOR X George W. Sherouse X 6 January 1985 X X --------------------------------------------------------------------------- X*/ X X{ X erase_char = get_erase(); X initscr(); X raw(); X noecho(); X} SHAR_AND_ENJOY if test 690 -ne "`wc -c < 'init_term.c'`" then echo shar: error transmitting "'init_term.c'" '(should have been 690 characters)' fi fi # end of overwriting check echo shar: extracting "'pick_one.c'" '(2511 characters)' if test -f 'pick_one.c' then echo shar: will not over-write existing file "'pick_one.c'" else sed 's/^ X//' << \SHAR_AND_ENJOY > 'pick_one.c' X#include X#include X#include X#include "c_term.h" X Xint pick_one(ChoiceList, ChoiceCount) Xchar **ChoiceList; Xint ChoiceCount; X X/* X --------------------------------------------------------------------------- X X Last revision - X 6 January 1985 - GWS X Change to use curses X X 16 November 1984 - GWS X Ignore XON, XOFF X X 12 April 1984 - GWS X X X NAME X pick_one - "crash-proof" routine for picking one of a list of X list of strings X X SYNOPSIS X int pick_one(ChoiceList, ChoiceCount) X char **ChoiceList; X int ChoiceCount; X X DESCRIPTION X This routine prompts and nudges the user through selection of a X string from a table of strings - useful for choosing an item X from a menu for instance. The options are displayed one at a X time. The current item is selected by pressing return. The X space bar advances, the up-arrow backs up. The return X value of the function is the index of the chosen string. X X SEE ALSO X X X DIAGNOSTICS X none X X BUGS X none known X X AUTHOR X George W. Sherouse X 11 April 1984 X X --------------------------------------------------------------------------- X*/ X X{ X int c; X int val; X int biggest; X int temp; X int loop; X int where_y, X where_x; X char Format[80]; X X int strlen(); X X/* XIn the silly case where there is only one choice, just print it Xand return the index 0. X*/ X if (ChoiceCount == 1) X { X printw("%s", ChoiceList[0]); X return(0); X } X/* XFind the longest string in the bunch X*/ X biggest = strlen(ChoiceList[0]); X for (loop = 1; loop < ChoiceCount; loop++) X if ((temp = strlen(ChoiceList[loop])) > biggest) X biggest = temp; X X getyx(stdscr, where_y, where_x); X standout(); X for (loop = 0; loop < biggest; loop++) X printw(" "); X X sprintf(Format, "%%-%ds", biggest); X X val = 0; X while (1) X { X mvprintw(where_y, where_x, Format, ChoiceList[val]); X refresh(); X X switch (c = (getch() & 0177)) X { X#ifdef ABORT_CHAR X case ABORT_CHAR: X clear(); X standend(); X mvprintw(0, 0, "Program aborted at your request..."); X move(LINES - 1, 0); X refresh(); X endwin(); X exit(0); X break; X#endif ABORT_CHAR X X case '\015': X standend(); X mvprintw(where_y, where_x, Format, ChoiceList[val]); X refresh(); X return(val); X case ' ': X if (++val == ChoiceCount) X val = 0; X break; X case '^': X if (--val < 0) X val = ChoiceCount - 1; X break; X case '\021': X case '\023': X break; X default: X fprintf(stderr, "%c", '\007'); X } X } X} SHAR_AND_ENJOY if test 2511 -ne "`wc -c < 'pick_one.c'`" then echo shar: error transmitting "'pick_one.c'" '(should have been 2511 characters)' fi fi # end of overwriting check # End of shell archive exit 0