[comp.sources.unix] v14i093: Forms interface for shell scripts, Part02/02

rsalz@bbn.com (Rich Salz) (05/11/88)

Submitted-by: Paul Lew <harvard!gsg!lew@a.cs.uiuc.edu>
Posting-number: Volume 14, Issue 93
Archive-name: shellforms/part02



#! /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:
#	sf.c form.c load.c field.c selection.c keyword.c option.c
#	msg.c term.c io.c summary.c
export PATH; PATH=/bin:$PATH
echo shar: extracting "'sf.c'" '(4115 characters)'
if test -f 'sf.c'
then
	echo shar: will not over-write existing file "'sf.c'"
else
sed 's/^X//' << \SHAR_EOF > 'sf.c'
X/**************************************************************************
X*
X* File name:	sf.c
X*
X* Author:	Paul Lew, General Systems Group, Inc. Salem NH
X* Created at:	05/08/86  10:11 AM
X* Last update:	02/08/88  00:23 AM  (Edition: 29)
X*
X* Description:	This program will take standard input  (if no argument
X*		specified in  command line) or  the specified  file as
X*		form  template and  display   it  on  the terminal  to
X*		perform basic form editing function.  It then generate
X*		the Csh  or Bourne shell set script  on  stdout  to be
X*		executed (ala tset -s).
X*
X*		This program is designed to  give programmer  an  easy
X*		way of doing form filling in shell level.
X*
X* Update History:
X*
X*    Date	Modification Description				By
X*  --------	------------------------------------------------------	---
X*  05/08/86	Initial version						Lew
X*  08/04/87	added Help_display flag					Lew
X*  12/29/87	modify to add Bourne shell output flag, use getopt()	Lew
X*  01/12/88	added init_sno(), added CTRL L redisplay function,	Lew
X*		added signal trap handling.
X*  01/26/88	added AUTOTAB at end of a field, added NUMERIC field	Lew
X*		attribute
X*  02/08/88	modified to add perl script output flag			Lew
X*
X***************************************************************************/
X#define	EXTERN
X#include	<stdio.h>
X#include	<ctype.h>
X#include	"form.h"
X#include	"basic.h"
X
Xchar	*Version = "1.8  02/08/88  00:21 AM";
Xchar	*Bugs = "Bug report send to: decvax!gsg!lew (UUCP)";
Xchar	*Copyright = "Copyright by Paul Lew (1987,1988) All rights reserved";
Xchar	*Prgname;			/* program name */
X
Xextern	unsigned char	Shell;
Xextern	int		Help_display;
Xint			Debug = NO;
X
X/*------------------------------------------------------------07/13/84--+
X|									|
X|	    M a i n    R o u t i n e    S t a r t s    H e r e		|
X|									|
X+----------------------------------------------------------------------*/
Xmain (argc, argv)
Xint	argc;		/* number of argument passed */
Xchar	**argv;		/* pointer to argument list */
X	{
X	int		n;		/* number of files (so far 2)	*/
X	char		*fname;		/* form file name */
X
X	Prgname = *argv;
X	n = procarg (argc, argv);
X	if (n == argc) fname = NULL;	/* read from stdin if no input	*/
X	else fname = argv[n];
X	edit_form (fname, (int (*)())NULL);
X	exit (0);
X	}
X
X/*----------------------------------------------------------------------+
X|									|
X|	proc_arg : process input argument and set global flags		|
X|									|
X+----------------------------------------------------------------------*/
Xprocarg (argc, argv)
Xint	argc;
Xchar	**argv;
X	{
X	int		rvideo = 0;
X	int		undline = 0;
X	int		hilite = 0;
X	char		*fname = NULL;
X	int		c;
X	extern	char	*optarg;	/* ptr to argument */
X	extern	int	optind;		/* remember which one to process next */
X
X	ENTER (procarg);
X	while ((c = getopt (argc, argv, "Hbdhmo:pru")) != EOF) {
X		switch (c) {
X			when 'b': Shell = BOURNE;
X			when 'd': Debug = YES;
X			when 'h': hilite = YES;
X			when 'm': Help_display = YES;
X			when 'o': fname = optarg;
X			when 'p': Shell = PERL;
X			when 'r': rvideo = YES;
X			when 'u': undline = YES;
X			otherwise:help ();
X				  exit (1);
X			}
X		}
X	set_options (hilite, rvideo, undline, fname);
X	RETURN (optind);
X	}
X
X/*-------------------------------------------------------------05/08/86-+
X|									|
X|		       help : display help message			|
X|									|
X+----------------------------------------------------------------------*/
Xhelp ()
X	{
X	ENTER(help);
X	fprintf (stderr, "%s Version %s\r\n", Prgname, Version);
X	fprintf (stderr, "Command Options:\r\n");
X	fprintf (stderr, "  -H        display this help message\r\n");
X	fprintf (stderr, "  -b        generate Bourne shell output [Csh]\r\n");
X	fprintf (stderr, "  -d        debug mode, will show CTRL chars\r\n");
X	fprintf (stderr, "  -h        input in highlight mode\r\n");
X	fprintf (stderr, "  -m        display selection help automatically\r\n");
X	fprintf (stderr, "  -o file   use file as output file\r\n");
X	fprintf (stderr, "  -p        generate perl script output\r\n");
X	fprintf (stderr, "  -r        input in reverse video mode\r\n");
X	fprintf (stderr, "  -u        input in underline mode\r\n");
X	EXIT;
X	}
SHAR_EOF
if test 4115 -ne "`wc -c < 'sf.c'`"
then
	echo shar: error transmitting "'sf.c'" '(should have been 4115 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'form.c'" '(5898 characters)'
if test -f 'form.c'
then
	echo shar: will not over-write existing file "'form.c'"
else
sed 's/^X//' << \SHAR_EOF > 'form.c'
X/* Last update: 02/08/88  00:18 AM  (Edition: 56) */
X#include	<stdio.h>
X#include	<ctype.h>
X#include	<signal.h>
X#include	"form.h"
X#include	"field.h"
X#include	"term.h"
X#include	"basic.h"
X
Xchar	Screen [SCRLINE][SCRCOL+1];
Xchar	Form_name[20] = "";		/* current form name */
Xchar	Exitc;				/* field exit char */
X 
Xchar	Enter_mode [20];		/* display before input field */
Xchar	Exit_mode [20];			/* display after input field */
X
Xstruct	field	Field[MAXFIELD];	/* field nodes */
Xint		Fno;			/* next field to use (or count) */
Xunsigned char	Fhead[SCRLINE];		/* 1st field index on each line */
Xunsigned char	Flcount[SCRLINE];	/* number of fields on this line */
Xunsigned char	Lastdata = 24;		/* last line with data on form */
X
Xchar	Varfile [MAXFNAME];		/* output variable file name */
X
Xextern	int		Form_msg;	/* defined in msg.c */
Xextern	unsigned char	Shell;		/* output shell script type */
X
Xint	sig_interrupt();
Xint	sig_stop();
X
X/*----------------------------------------------------------------------+
X|									|
X|		show_form : display a given form file			|
X|									|
X+----------------------------------------------------------------------*/
Xshow_form (fname)
Xchar	*fname;		/* name of form file, NULL = stdin, 1 = redisplay */
X	{
X	int		i, j;
X	int		idx;		/* index to current field */
X	unsigned	size;
X	unsigned	off;
X	unsigned	len;		/* string length */
X	int		pend;		/* previous end position */
X	char		*lp;		/* line pointer (for speed) */
X	char		*p;
X	extern	char	*Prgname;
X
X	ENTER(show_form);
X	if (fname != (char *)1 &&		/* redisplay */
X	    (fname == NULL || strcmp (fname, Form_name) != 0)) {
X		if (!load_form (fname)) RETURN (0);
X		}
X
X	screen (SCR_ERASE);
X	for (i=0; i<SCRLINE; i++) {
X		p = lp = Screen[i];
X		if (Flcount[i] != 0) {
X			pend = 0;
X			for (j=0, idx=Fhead[i]; j<Flcount[i]; j++, idx++) {
X				size = Field[idx].f_len;
X				off = Field[idx].f_off;
X				put_string (p, off-pend);
X				put_string (Enter_mode, 0); 
X				put_string (lp + off, size);
X				put_string (Exit_mode, 0);
X				p = lp + off + size;
X				pend = off + size;
X				}
X			}
X		if ((len = strlen (p)) == 0) continue;
X		put_string (p, len);
X		put_char ('\r');
X		}
X	RETURN (1);
X	}
X
X/*----------------------------------------------------------------------+
X|									|
X|	   edit_form : edit a form on all the input fields		|
X|									|
X+----------------------------------------------------------------------*/
Xedit_form (fname, action)
Xchar	*fname;		/* name of the form to edit */
Xint	(*action) ();	/* action routine to check at end of each field */
X	{
X	unsigned	fdx = 0;	/* current cursor in field index */
X	struct	field	*fp;		/* pointer to current edit field */
X	int		n;		/* action routine return status */
X	int		efopt;		/* option to edit field */
X
X	ENTER(edit_form);
X	signal (SIGINT, sig_interrupt);
X	signal (SIGTSTP, sig_stop);
X
X	term_init ();
X	cbreakio (1);
X	if (!show_form (fname)) goto end;
X	if (Fno == 0) goto end;
X 
X	form_msg ((char *)NULL, 1, 1);
X	screen (SCR_KEYXMIT);
X	while (1) {
X		fp = &Field[fdx];
X		efopt = EF_BOF;
X		do	{
X			if (fp->f_attr & FA_SELECTION) sel_field (fdx);
X			else edit_field (fdx, efopt);
X			if (!action) break;
X			n = (*action) (fdx, &Screen[fp->f_line-1][fp->f_off],
X					fp->f_len, Exitc);
X			switch (n) {
X				when EF_ERR:	efopt = EF_BOF;
X				when EF_FILL:	efopt = EF_FILL;
X				}
X			} while (n != EF_OK);
X 
X		if ((Exitc & 0x80) == 0x80) {
X			switch (Exitc & 0x7f) {
X				when KU:	Exitc = CTRL('P');
X				when KD:	Exitc = CTRL('N');
X				}
X			}
X		switch (Exitc) {
X			when CTRL('L'):	show_form ((char *)1);
X			when CTRL('M'): goto wrout;
X			when CTRL('J'):	goto wrout;
X			when CTRL('P'):	fdx = closest (fdx, -1);
X			when CTRL('N'):	fdx = closest (fdx, 1);
X			when CTRL('T'): fdx = (fdx == 0) ? Fno-1 : (fdx-1);
X			when CTRL('I'): if (++fdx == Fno) fdx = 0;
X			otherwise:	show_summary ();
X					show_form ((char *)1);
X			}
X		}
Xwrout:	write_var ();
X	poscur (Lastdata, (unsigned char)1, "\n"); screen (SCR_EEOL);
Xend:
X	screen (SCR_NOKEYXMIT);
X	cbreakio (0);
X	term_close ();
X	EXIT;
X	}
X
X/*-------------------------------------------------------------05/08/86-+
X|									|
X|	       write_var : write field variables to a file		|
X|									|
X+----------------------------------------------------------------------*/
Xwrite_var ()
X	{
X	register int	i;
X	FILE		*fd;		/* output file pointer */
X	char		*p;
X	char		*op;
X	char		c;
X	char		buf[80+1];
X	char		obuf[80+1];
X	struct	field	*f;
X
X	ENTER(write_var);
X	if (!strlen (Varfile)) EXIT;
X
X	if ((fd = fopen (Varfile, "w")) == NULL) {
X		fprintf (stderr, "write_var: can not open file %s for write\r\n",
X			 Varfile);
X		exit (1);
X		}
X
X	for (i=0; i<Fno; i++) {
X		f = &Field[i];
X		if (f-> f_var != NULL) {
X			get_field (i, buf);
X			p = buf;  op = obuf;
X			while (c = *p++) {
X				switch (c) {
X				    when '\'':	if (Shell== PERL) *op++ = '\\';
X						else	{
X							*op++ ='\'';*op++ ='"';
X							*op++ ='\'';*op++ ='"';
X							}
X				    when '!':	if (Shell == CSH) *op++ = '\\';
X				    }
X				*op++ = c;
X				}
X			*op = EOS;
X			fprintf (fd, "%s%s='%s'%s\n",
X				 (Shell==CSH)?"set ":((Shell==PERL)?"$":""),
X				 f-> f_var, obuf,
X				 (Shell == PERL) ? ";" : "");
X			}
X		}
X	fclose (fd);
X	EXIT;
X	}
X
X/*-------------------------------------------------------------01/12/88-+
X|									|
X|		 sig_interrupt : Interrupt signal handler		|
X|									|
X+----------------------------------------------------------------------*/
Xsig_interrupt ()
X	{
X	ENTER (sig_interrupt);
X	form_msg ("Aborted by user\n", 24+1, 1);
X	screen (SCR_NORMAL);
X	cbreakio (1);
X	exit (1);
X	}
X
X/*-------------------------------------------------------------01/12/88-+
X|									|
X|		      sig_stop : Stop signal handler			|
X|									|
X+----------------------------------------------------------------------*/
Xsig_stop ()
X	{
X	ENTER (sig_stop);
X	form_msg ("stopped by user\n", 24+1, 1);
X	screen (SCR_NORMAL);
X	cbreakio (0);
X	kill (getpid(), SIGSTOP);
X	put_string ("Press CTRL L to refresh display: ", 33);
X	cbreakio (1);
X	}
SHAR_EOF
if test 5898 -ne "`wc -c < 'form.c'`"
then
	echo shar: error transmitting "'form.c'" '(should have been 5898 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'load.c'" '(8779 characters)'
if test -f 'load.c'
then
	echo shar: will not over-write existing file "'load.c'"
else
sed 's/^X//' << \SHAR_EOF > 'load.c'
X/* Last update: 01/26/88  10:53 PM  (Edition: 63) */
X#include	<stdio.h>
X#include	<strings.h>
X#include	"form.h"
X#include	"field.h"
X#include	"basic.h"
X
X#define	TOKENSIZE	256
X
Xchar	Varname [MAXVNAME];		/* variable name string pool */
Xchar	*Varwp = Varname;		/* next write position */
X
Xextern	char		Screen[SCRLINE][SCRCOL+1];
Xextern	char		Form_name[];
Xextern	unsigned char	Fhead[];	/* 1st field index on each line */
Xextern	unsigned char	Flcount[];	/* number of fields on this line */
Xextern	unsigned char	Lastdata;
Xextern	struct	field	Field[];	/* field nodes */
Xextern	int		Fno;		/* next field to use (or count) */
X
X/*----------------------------------------------------------------------+
X|									|
X|		load_form : load a form from disk file			|
X|									|
X+----------------------------------------------------------------------*/
Xload_form (fname)
Xchar	*fname;
X	{
X	FILE			*fp;
X	register unsigned char	i;
X
X	ENTER (load_form);
X	if (fname == NULL) fp = stdin;
X	else if ((fp = fopen (fname, "r")) == 0) {
X		fprintf (stderr, "Can not open form file %s\r\n", fname);
X		RETURN (0);
X		}
X	for (i=0; i<SCRLINE; i++) Screen[i][0] = '\0';
X	init_field ();
X	for (i=0; i<SCRLINE; i++) {
X		if (fgets (Screen[i], SCRCOL+1, fp) == 0) break;
X		if (Screen[i][0] == CTRL('L')) {
X			Screen[i][0] = EOS;
X			field_attr (fp);
X			break;
X			}
X		make_field (i+1, Screen[i]);
X		}
X	init_sno ();		/* fill data for field with selections */
X	Lastdata = i;
X	if (fname != NULL) {
X		strcpy (Form_name, fname);
X		}
X	RETURN (1);
X	}
X
X/*----------------------------------------------------------------------+
X|									|
X|    bcopy : copy len byte from src to dest (extra fill with blanks)	|
X|									|
X+----------------------------------------------------------------------*/
Xbcopy (dest, src, len)
Xchar		*dest;
Xchar		*src;
Xunsigned	len;
X	{
X	char		c = ' ';
X
X	ENTER (bcopy);
X	while (len-- != 0) {
X		if (c == EOS) *dest++ = ' ';	/* fill blanks to end */
X		else if ((c = *src++) != EOS)
X			*dest++ = c;
X		else	*dest++ = ' ';
X		}
X	EXIT;
X	}
X
X/*-------------------------------------------------------------05/08/86-+
X|									|
X|	   add_var : add a variable name to field structure		|
X|									|
X+----------------------------------------------------------------------*/
Xadd_var (fno, name)
Xint	fno;
Xchar	*name;
X	{
X	int		len = strlen (name) + 1;
X
X	ENTER (add_var);
X	if (Varwp + len >= &Varname[MAXVNAME]) {
X		fprintf (stderr, "add_var: no more space for variable name\r\n");
X		exit (1);
X		}
X	Field[fno].f_var = Varwp;
X	strcpy (Varwp, name);
X	Varwp += len;
X	EXIT;
X	}
X
X/*-------------------------------------------------------------05/08/86-+
X|									|
X|	  field_attr : read in field attribute of the form		|
X|									|
X+----------------------------------------------------------------------*/
Xfield_attr (fd)
XFILE	*fd;
X	{
X	int		field = -1;
X	char		tokbuf [TOKENSIZE];	/* token value */
X	char		token;			/* token specifier */
X	int		i, n;
X	unsigned	len, size;
X	struct	field	*f;
X	char		*p;
X
X	ENTER (field_attr);
X	while (token = get_token (fd, tokbuf)) {
X		switch (token) {
X			when 'v': if (++field >= Fno) RETURN (0);
X				  add_var (field, tokbuf);
X			when 's': n = (field < 0) ? 0 : field;
X				  f = &Field[n];
X				  size = strlen(tokbuf);
X				  build_selection (f, tokbuf, size);
X			when 'h': n = (field < 0) ? 0 : field;
X				  f = &Field[n];
X				  build_help_msg (f, tokbuf);
X			when 'd': n = (field < 0) ? 0 : field;
X				  f = &Field[n];
X				  size = strlen(tokbuf);
X				  len = (size > f-> f_len) ? f-> f_len : size;
X				  for (p=tokbuf, i=0; i<len; i++) {
X					  Screen[f-> f_line - 1][f-> f_off + i] = *p++;
X					  }
X			when 'a': n = (field < 0) ? 0 : field;
X				  f = &Field[n];
X				  set_field_attr (f, tokbuf);
X			otherwise:fprintf (stderr, "unknown token %c (field %d)\r\n",
X					   token, field);	
X			}
X		}
X	RETURN (1);
X	}
X
X/*-------------------------------------------------------------05/08/86-+
X|									|
X|     get_token : return next token in field description section	|
X|									|
X+----------------------------------------------------------------------*/
Xget_token (fd, tokbuf)
XFILE	*fd;
Xchar	*tokbuf;
X	{
X	static	char	buf[TOKENSIZE];
X	static	char	*p;
X	static	int	len = 0;
X	static	char	dchar;
X	register char	*tp;		/* temp pointer */
X	char		token;
X
X	ENTER (get_token);
X	if (len == 0) {
X		do	{
X			if (!fgets (buf, sizeof (buf), fd)) RETURN ((char)0);
X			len = strlen (buf) - 1;		/* no NL */
X			} while (len == 0);
X		dchar = buf[0];		/* delimiter char */
X		p = buf + 1;		/* 1st char */
X		}
X
X	for (tp=p; tp < &buf[len]; ) {
X		if (*tp++ == dchar) break;
X		}
X
X	token = *p++;			/* return token char */
X	p++;				/* skip =, actually ignore it */
X	while (p < tp-1)
X		*tokbuf++ = *p++;
X	*tokbuf = EOS;
X
X	if ((p = tp) == &buf[len]) len = 0;
X	RETURN (token);
X	}
X 
X/*----------------------------------------------------------------------+
X|									|
X|	make_field : extract input fields to make field structure	|
X|									|
X+----------------------------------------------------------------------*/
Xmake_field (lno, line)
Xunsigned	lno;		/* line number of this line */
Xchar		*line;
X	{
X	char		*p;
X	unsigned	col = 1;	/* current column position */
X	unsigned	in_field = 0;	/* number of input field char */
X	unsigned	cno;
X
X	ENTER (make_field);
X	for (p=line; *p != EOS; p++) {
X		switch (*p) {
X			case '~':	 /* input field */
X				*p = ' ';
X				if (in_field++ == 0) cno = col;
X				col++;
X				break;
X			case '\t':
X				col = ((col-1)/8 + 1) * 8 + 1;
X				goto lab;
X			default:
X				col++;
Xlab:				if (in_field)
X					add_field (lno, cno, p-line-in_field,
X						   in_field);
X				in_field = 0;
X			}
X		}
X	EXIT;
X	}
X
X/*----------------------------------------------------------------------+
X|									|
X|	init_field : initialize all field control related data		|
X|									|
X+----------------------------------------------------------------------*/
Xinit_field ()
X	{
X	int		i;
X
X	ENTER (init_field);
X	Fno = 0;
X	for (i=0; i<SCRLINE; i++) {
X		Fhead[i] = 0;
X		Flcount[i] = 0;
X		}
X	EXIT;
X	}
X 
X/*----------------------------------------------------------------------+
X|									|
X|	    add_field : add a given field to field structure		|
X|									|
X+----------------------------------------------------------------------*/
Xadd_field (line, column, offset, len)
Xunsigned	line;		/* line of the field */
Xunsigned	column;		/* column of the field */
Xunsigned	offset;		/* char offset from beginning of the line */
Xunsigned	len;		/* field size */
X	{
X	struct	field	*fp;
X
X	ENTER (add_field);
X	if (Fno >= MAXFIELD) {
X		fprintf (stderr, "Too many fields in a screen max=%d\r\n",
X			 MAXFIELD);
X		exit (1);
X		}
X	fp = &Field[Fno];
X	fp-> f_line = line;
X	fp-> f_col = column;
X	fp-> f_off = offset;
X	fp-> f_len = len;
X	fp-> f_attr = 0;		/* 'a' -- attribute */
X	fp-> f_sel = NULL;		/* 's' -- selection */
X	fp-> f_help = NULL;		/* 'h' -- help message */
X	fp-> f_sno = 0;
X	fp-> f_var = NULL;
X 
X	if (Flcount[line-1]++ == 0) {
X		Fhead[line-1] = Fno;
X		}
X	Fno++;
X	EXIT;
X	}
X
X#define	STRNEQ(x,y,n)	((*(x) == *(y)) && strncmp (x,y,n) == 0)
X#define	BADINIT	"Field %d, Init value: [%.*s] no in selection list, ignored\n"
X/*-------------------------------------------------------------01/11/88-+
X|									|
X|       init_sno : initialize selection number for preloaded fields	|
X|									|
X+----------------------------------------------------------------------*/
Xinit_sno ()
X	{
X	register int	idx, j;
X	int		field_count;
X	int		init_size;	/* initial default data size */
X	struct	field	*f;
X	char		*p;
X
X	ENTER (init_sno);
X	for (idx=0; idx<Fno; idx++) {
X
X	    f = &Field[idx];
X	    p = &Screen[f-> f_line - 1][f-> f_off];
X	    init_size = fldlen (p, f-> f_len);
X
X	    if (f-> f_sel != NULL) {
X		if (init_size) {
X			field_count = sel_num (f);
X			/* check if default data is in the selection list */
X			for (j=0; j<field_count; j++) {
X				register char	*selp;
X				selp = f-> f_sel[j];
X				if (STRNEQ (p, selp, strlen(selp))) {
X					f-> f_sno = j;
X					break;
X					}
X				}
X			if (j >= field_count) {
X				fprintf (stderr, BADINIT, idx, init_size, p);
X				j = 0;  goto mv_1st;
X				}
X			}
X		else	{
X			/* move the first selection into the field */
X			j = 0;
Xmv_1st:			strncpy (p, f-> f_sel[j], strlen(f-> f_sel[j]));
X			}
X		}
X	    }
X	EXIT;
X	}
X
X/*-------------------------------------------------------------01/26/88-+
X|									|
X|	    set_field_attr : set attributes for a given field		|
X|									|
X+----------------------------------------------------------------------*/
Xset_field_attr (fieldp, buf)
Xstruct	field	*fieldp;
Xchar		*buf;
X	{
X	char	c;
X
X	ENTER (set_field_attr);
X	while ((c = *buf++) != EOS) {
X		switch (c) {
X		    when 'd':	fieldp-> f_attr |= FA_NUMERIC;
X		    when 'a':	fieldp-> f_attr |= FA_AUTOTAB;
X		    when 'b':	fieldp-> f_attr |= FA_BLOCK;
X		    otherwise:	fprintf (stderr,
X					 "unknown field attribute: %c\r\n", c);
X				exit (1);
X		    }
X		}
X	EXIT;
X	}
SHAR_EOF
if test 8779 -ne "`wc -c < 'load.c'`"
then
	echo shar: error transmitting "'load.c'" '(should have been 8779 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'field.c'" '(6631 characters)'
if test -f 'field.c'
then
	echo shar: will not over-write existing file "'field.c'"
else
sed 's/^X//' << \SHAR_EOF > 'field.c'
X/* Last update: 01/26/88  11:26 PM  (Edition: 25) */
X#include	<stdio.h>
X#include	<signal.h>
X#include	<strings.h>
X#include	<ctype.h>
X#include	"term.h"
X#include	"form.h"
X#include	"field.h"
X#include	"basic.h"
X
Xextern	int		Fno;
Xextern	struct	field	Field[];
Xextern	char		Screen[SCRLINE][SCRCOL+1];
Xextern	char		Enter_mode[];
Xextern	char		Exit_mode[];
Xextern	int		Form_msg;
Xextern	char		Exitc;
X
X/*-------------------------------------------------------------05/09/86-+
X|									|
X|	      get_field : get a copy of field data to buffer		|
X|									|
X+----------------------------------------------------------------------*/
Xget_field (fno, buf)
Xint	fno;				/* field number */
Xchar	*buf;				/* buffer to be filled */
X	{
X	struct	field	*f;
X	char		*p;
X	int		size;
X
X	ENTER(get_field);
X	if (fno < 0 || fno >= Fno) EXIT;
X	f = &Field[fno];
X	p = &Screen [f-> f_line -1][f-> f_off];
X	size = fldlen (p, f-> f_len);
X	strncpy (buf, p, size);
X	buf[size] = EOS;		/* mark the end */
X	EXIT;
X	}
X/*----------------------------------------------------------------------+
X|									|
X|  fldlen : return the number of data in a field (skip trailing blanks) |
X|									|
X+----------------------------------------------------------------------*/
Xfldlen (buf, size)
Xchar		*buf;		/* pointer to field buffer */
Xunsigned	size;		/* size of the field */
X	{
X	int		blank;
X
X	ENTER(fldlen);
X	for (blank=0; buf[size-1-blank] == ' '; blank++) {
X		if (blank >= size) break;
X		}
X	RETURN (size - blank);		/* return length of field */
X	}
X
X/*----------------------------------------------------------------------+
X|									|
X|	  upd_field : move data into a field and display it		|
X|									|
X+----------------------------------------------------------------------*/
Xupd_field (idx, type, data)
Xunsigned	idx;		/* field number (0 to Fno-1) */
Xint		type;		/* type of output */
Xint		data;		/* data, type may vary */
X	{
X	struct	field	*fp;
X	char		*fmt;
X	char		*scp;		/* pointer to screen buffer */
X	char		buf[81];
X	int		data2;		/* cents */
X
X	ENTER(upd_field);
X	if (idx >= Fno) {
X		fprintf (stderr,
X			 "Field number: %d out of range, max %d\r\n",
X			 idx, Fno);
X		EXIT;
X		}
X 
X	fp = &Field[idx];
X	switch (type) {
X		case UF_MONEY:	fmt = "%5d.%02d";
X				data2 = data % 100;
X				data = data / 100;	break;
X		case UF_NUMBER: fmt = "%d";		break;
X		case UF_STRING:
X		default:	fmt = "%s";		break;
X		}
X 
X	sprintf (buf, fmt, data, data2);
X	scp = &Screen[fp-> f_line - 1][fp-> f_off];
X	bcopy (scp, buf, (unsigned)fp-> f_len);
X	poscur (fp-> f_line, fp-> f_col, (char *)NULL);
X	put_string (scp, fp-> f_len);
X	poscur (fp-> f_line, fp-> f_col, (char *)NULL);
X	EXIT;
X	}
X
X/*-------------------------------------------------------------07/14/87-+
X|									|
X|	closest : find the closest field above/below current line	|
X|									|
X+----------------------------------------------------------------------*/
Xclosest (fno, direction)
Xunsigned	fno;		/* current field number */
Xint		direction;	/* compare direction: 1=below, -1=above */
X	{
X	struct	field	*fp = &Field[fno];
X	int		col;		/* target column */
X	int		line;		/* current line */
X	int		diff;		/* current difference */
X	int		mindiff = 100;	/* minimal difference */
X	int		mini = 0;	/* minimal field index */
X	register int	i;
X
X	ENTER(closest);
X	col = fp->f_col;
X	line = fp->f_line;
X
X	for (i=fno+direction; i != fno; i += direction) {
X		if (i < 0) i = Fno-1;
X		else if (i >= Fno) i = 0;
X		fp = &Field[i];
X		if (fp->f_line != line) break;
X		}
X	mini = i;
X	for (line = fp->f_line; ; i += direction) {
X		if (i < 0) i = Fno-1;
X		else if (i >= Fno) i = 0;
X		fp = &Field[i];
X		if (fp->f_line != line) break;
X		if ((diff = abs ((int)fp->f_col - (int)col)) == 0) RETURN (i);
X		if (diff < mindiff) {
X			mindiff = diff;
X			mini = i;
X			}
X		}
X	RETURN (mini);
X	}
X
X/*----------------------------------------------------------------------+
X|									|
X|		edit_field : edit a given field in a form		|
X|									|
X+----------------------------------------------------------------------*/
Xedit_field (idx, efopt)
Xunsigned	idx;			/* index to Field array */
Xint		efopt;			/* option */
X	{
X	struct	field	*fp;
X	char		c;
X	char		*p;
X	char		*s;		/* beginning of field buffer */
X	unsigned	n;
X	register int	i;
X
X	ENTER (edit_field);
X	fp = &Field[idx];
X	poscur (fp-> f_line, fp-> f_col, Enter_mode);
X	p = s = &Screen [fp-> f_line - 1][fp-> f_off];
X	switch (efopt) {
X		case EF_FILL:
X		case EF_EOF:	n = fldlen (s, fp-> f_len);
X				if (n != 0) {
X					if (efopt == EF_FILL)
X						put_string (p, n);
X					p += n;
X					}
X				break;
X		default:	;	/* start at beginning of field */
X		}
X	while (1) {
X		c = getkey ();
X		if (Form_msg) {
X			form_msg ((char *)NULL, fp-> f_line, fp-> f_col + (p-s));
X			put_string (Enter_mode, 0);
X			}
X		if ((c & 0x80) == 0x80) {
X			switch (c & 0x7f) {
X				case KL:	goto cur_left;
X				case KR:	goto cur_right;
X				}
X			}
X		switch (c) {
X			case '\177':		/* delete char */
X				if (p > s) { *(--p) = ' '; screen (SCR_DEL); }
X				continue;
X			case CTRL('W'):		/* delete prev word */
X				while (p > s) {
X					if (*(p-1) != ' ') break;
X					p--; screen (SCR_DEL);
X					}
X				while (p > s) {
X					if (*(p-1) == ' ') break;
X					*(--p) = ' ';
X					screen (SCR_DEL);
X					}
X				continue;
X			case CTRL('K'):
X				n = fldlen (s, fp-> f_len);
X				for (i=0; i<n; i++) put_char (*(p+i) = ' ');
X				for (i=0; i<n; i++) screen (SCR_BACKSPACE);
X				continue;
X			case CTRL('H'):
X			case CTRL('B'):
Xcur_left:			if (p > s) { p--; screen (SCR_BACKSPACE); }
X				continue;
X			case CTRL('F'):
Xcur_right:			if (p < s + fp-> f_len) {
X					put_char (*p++);
X					}
X				continue;
X			case CTRL('G'):
X			case CTRL('U'):
X				while (p > s) {
X					*(--p) = ' ';  screen (SCR_DEL);
X					}
X				continue;
X			case CTRL('E'):		/* goto end of field */
X				n = fldlen (s, fp-> f_len);
X				p = s + n;
X				poscur (fp-> f_line, fp-> f_col + n, (char *)NULL);
X				continue;
X			case CTRL('A'):		/* emacs style */
X				p = s;
X				poscur (fp-> f_line, fp-> f_col, (char *)NULL);
X				continue;
X			case CTRL('O'):
X				prev_msg ();
X				continue;
X			default:
X				if ((fp-> f_attr & FA_NUMERIC) != 0 &&
X				     isprint (c) && !isdigit (c)) {
X					put_char (CTRL('G'));
X					form_msg ("Numeric field, 0-9 only",
X						  fp-> f_line,
X						  fp-> f_col + (p-s));
X					continue;
X					}
X				if (c < LOW_GCHAR || c > HIGH_GCHAR) {
X					Exitc = c;	/* save exit char */
X					goto eoe;
X					}
X			}
X		if (p - s >= fp-> f_len) { put_char (CTRL('G')); continue; }
X		*p++ = c;
X		put_char (c);
X		if ((fp-> f_attr & FA_AUTOTAB) != 0 && p - s == fp-> f_len) {
X			Exitc = TAB;		/* tab to next field */
X			break;
X			}
X		}
X	/* *p = EOS will put a marker at the end of buffer */
Xeoe:	put_string (Exit_mode, 0);
X	RETURN (p-s);
X	}
SHAR_EOF
if test 6631 -ne "`wc -c < 'field.c'`"
then
	echo shar: error transmitting "'field.c'" '(should have been 6631 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'selection.c'" '(5773 characters)'
if test -f 'selection.c'
then
	echo shar: will not over-write existing file "'selection.c'"
else
sed 's/^X//' << \SHAR_EOF > 'selection.c'
X/* Last update: 01/27/88  00:04 AM  (Edition: 45) */
X#include	<stdio.h>
X#include	<sys/ioctl.h>
X#include	<ctype.h>
X#include	<strings.h>
X#include	"term.h"
X#include	"form.h"
X#include	"field.h"
X#include	"basic.h"
X
Xint	Help_display = NO;		/* if YES, display help */
X
Xextern	struct	field	Field[];
Xextern	char		Enter_mode[];
Xextern	char		Exit_mode[];
Xextern	int		Form_msg;
Xextern	char		Exitc;
Xextern	char		*malloc();
Xextern	char		*calloc();
X/*
X    Selection buffer looks like:
X
X	<delchr> string1 <delchr> string2 <delchr> ... stringn <delchr>
X
X    The first character in the buffer will be used as the delimiter to
X    separate selection strings.  The last delimiter character is optional,
X    i.e., EOS will also terminate the last selection string.
X*/
X
X/*-------------------------------------------------------------08/01/87-+
X|									|
X|     build_selection : take selection definition and create a list	|
X|									|
X+----------------------------------------------------------------------*/
Xbuild_selection (fldp, buf, len)
Xstruct	field	*fldp;			/* ptr to field structure */
Xchar		*buf;			/* selection strings */
Xunsigned	len;			/* length of string */
X	{
X	register char	*p = (char *)malloc(len+1);
X	register char	**tp;
X	register int	i;
X	char		delimiter = buf[0];	/* selection delimiter */
X	char		c;
X	unsigned	cnt = 0;		/* # of selections */
X	char		*tmp[50];		/* temp array */
X
X	ENTER(build_selection);
X	if (len == 0) len = strlen (buf);
X	while (len-- != 0) {
X		if ((c = *buf++) == delimiter) {
X			*p++ = EOS;
X			if (cnt >= 50) {
X				/* silent ignored extra for now */
X				}
X			else tmp[cnt++] = p;
X			}
X		else	*p++ = c;
X		}
X	fldp->f_sel = tp = (char **) malloc (sizeof (char *) * (cnt + 1));
X	for (i=0; i<cnt; i++) *tp++ = tmp[i];
X	*tp = NULL;
X	fldp->f_attr |= FA_SELECTION;
X	RETURN (0);
X	}
X
X/*-------------------------------------------------------------08/01/87-+
X|									|
X|	sel_num : return the number of selections in a given field	|
X|									|
X+----------------------------------------------------------------------*/
Xsel_num (fldp)
Xstruct	field	*fldp;
X	{
X	register int	i = 0;
X	register char	**pp = fldp-> f_sel;
X
X	ENTER(sel_num);
X	while (*pp++ != NULL) i++;
X	RETURN (i);
X	}
X
X/*-------------------------------------------------------------08/01/87-+
X|									|
X|	sel_field : allow user to select a selection from the list	|
X|									|
X+----------------------------------------------------------------------*/
Xsel_field (idx)
Xunsigned	idx;			/* index to Field array */
X	{
X	struct	field	*fldp = &Field[idx];
X	int		n = fldp-> f_sno;	/* selection number */
X	int		selno;			/* # of possible selections */
X	int		i = -1;
X	char		c;
X
X	ENTER(sel_field);
X	selno = sel_num (fldp);
X	poscur (fldp-> f_line, fldp-> f_col, Enter_mode);
X	upd_field (idx, UF_STRING, fldp-> f_sel[n]);
X	while (1) {
X		int	might_tab;
X		if (Help_display) display_help (fldp, n);
X		c = getkey ();
X		might_tab = 0;
X		if (Form_msg) {
X			form_msg ((char *)NULL, fldp->f_line, fldp->f_col);
X			put_string (Enter_mode, 0);
X			}
X		if ((c & 0x80) == 0x80) {
X			switch (c & 0x7f) {
X				case KL:	goto prev_sel;
X				case KR:	goto next_sel;
X				}
X			}
X		switch (c) {
X			case ' ':
X			case CTRL('F'):
Xnext_sel:			if (++n >= selno) n = 0;  break;
X			case CTRL('H'):
Xprev_sel:			if (--n < 0) n = selno-1; break;
X			case '?':
X				if (!Help_display) {
X					display_help (fldp, n);
X					break;
X					}
X			default:if (c < LOW_GCHAR || c > HIGH_GCHAR) {
X					Exitc = c;
X					goto eoe;
X					}
X				i = cmp1st (c, fldp->f_sel, i+1);
X				if (i < 0) continue;
X				might_tab = 1;
X				n = i;
X			}
X		upd_field (idx, UF_STRING, fldp-> f_sel[n]);
X		if (might_tab && (fldp->f_attr & FA_AUTOTAB) != 0) {
X			Exitc = TAB;
X			break;
X			}
X		}
Xeoe:	put_string (Exit_mode, 0);
X	fldp-> f_sno = n;		/* save selection number */
X	EXIT;
X	}	
X
X/*-------------------------------------------------------------08/03/87-+
X|									|
X|	   cmp1st : compare 1st character in a keyword list		|
X|									|
X+----------------------------------------------------------------------*/
Xcmp1st (c, list, start)
Xchar	c;				/* char to compare */
Xchar	**list;				/* keyword list */
Xint	start;				/* start entry index */
X	{
X	register int	i, j;
X	register int	n;
X
X	ENTER(cmp1st);
X	if (list == NULL || list[0] == NULL) RETURN (-1);
X	for (n=0; list[n] != NULL; n++);
X	for (i=start, j=0; j<n; i++, j++) {
X		if (i >= n) i = 0;
X		if ((c | 0x20) == (list[i][0] | 0x20)) RETURN (i);
X		}
X	RETURN (-1);			/* no match */
X	}
X
X/*-------------------------------------------------------------08/04/87-+
X|									|
X|		build_help_msg : build help message list		|
X|									|
X+----------------------------------------------------------------------*/
Xbuild_help_msg (fldp, buf)
Xstruct	field	*fldp;			/* field where the msg belongs */
Xchar		*buf;			/* message stores here */
X	{
X	unsigned	len = strlen (buf);
X	unsigned	n;
X	register int	i;
X	register char	*p;
X
X	ENTER(build_help_msg);
X	n = sel_num (fldp);
X	if (fldp-> f_help == NULL) {		/* first time call */
X		fldp-> f_help = (char **) calloc(n+1, sizeof(char *));
X		}
X	for (i=0; i<n; i++) {
X		if (fldp-> f_help[i] == NULL) break;
X		}
X	if (i < n) {
X		fldp-> f_help[i] = p = (char *) malloc (len + 1);
X		strcpy (p, buf);
X		}
X	EXIT;
X	}
X
X/*-------------------------------------------------------------08/04/87-+
X|									|
X|	   display_help : display help message on message line		|
X|									|
X+----------------------------------------------------------------------*/
Xdisplay_help (fldp, i)
Xstruct	field	*fldp;			/* field pointer */
Xint		i;			/* index to help message */
X	{
X	char		*p;
X	int		numchar;	/* # of pending input chars */
X
X	ENTER(display_help);
X	if (fldp-> f_help == NULL) EXIT;
X	p = fldp-> f_help[i];
X	if (p != NULL) {
X		ioctl (0, FIONREAD, &numchar);
X		if (numchar == 0) form_msg (p, fldp->f_line, fldp->f_col);
X		}
X	EXIT;
X	}
SHAR_EOF
if test 5773 -ne "`wc -c < 'selection.c'`"
then
	echo shar: error transmitting "'selection.c'" '(should have been 5773 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'keyword.c'" '(1253 characters)'
if test -f 'keyword.c'
then
	echo shar: will not over-write existing file "'keyword.c'"
else
sed 's/^X//' << \SHAR_EOF > 'keyword.c'
X/* Last update: 01/13/88  10:43 AM  (Edition: 5) */
X#include	<stdio.h>
X#include	"basic.h"
X/*----------------------------------------------------------------------+
X|									|
X|	fill_keyword : fill the field with possible matched keyword	|
X|									|
X+----------------------------------------------------------------------*/
Xfill_keyword (buf, len, list)
Xchar		*buf;
Xunsigned	len;			/* size of input field */
Xchar		**list;
X	{
X	int		i, j;
X	unsigned	flen;		/* field length */
X	unsigned char	match[80];
X 
X	ENTER (fill_keyword);
X	flen = fldlen (buf, len);
X 
X	for (i=j=0; list[i] != NULL; i++) {
X		if (kwcmp (buf, list[i], flen) == 0) {
X			/* find a match */
X			match[j++] = i;
X			}
X		}
X	if (j == 1) bcopy (buf, list[match[0]], len);
X	else if (j > 1)	 bcopy (buf, list[match[0]], flen);
X 
X	RETURN (j);
X	}
X 
X/*----------------------------------------------------------------------+
X|									|
X|	kwcmp : compare a word with keyword (case insensitive)		|
X|									|
X+----------------------------------------------------------------------*/
Xkwcmp (src, dest, len)
Xchar		*src;
Xchar		*dest;
Xunsigned	len;
X	{
X	ENTER (kwcmp);
X	while (len-- != 0) {
X		if ((*src++ | 0x20) != (*dest++ | 0x20))
X			 RETURN (1);			/* no match */
X		}
X	RETURN (0);		/* match found */
X	}
SHAR_EOF
if test 1253 -ne "`wc -c < 'keyword.c'`"
then
	echo shar: error transmitting "'keyword.c'" '(should have been 1253 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'option.c'" '(1317 characters)'
if test -f 'option.c'
then
	echo shar: will not over-write existing file "'option.c'"
else
sed 's/^X//' << \SHAR_EOF > 'option.c'
X/* Last update: 01/13/88  11:17 AM  (Edition: 5) */
X#include	<stdio.h>
X#include	<strings.h>
X#include	"form.h"
X#include	"basic.h"
X
Xunsigned char	Rvideo;			/* reverse video */
Xunsigned char	Undline;		/* under line */
Xunsigned char	Hilite;			/* high light */
Xunsigned char	Shell = CSH;		/* output script type */
X
Xextern	char	Varfile[];
Xextern	char	Enter_mode[];
Xextern	char	Exit_mode[];
X 
X/*-------------------------------------------------------------05/08/86-+
X|									|
X|	       set_options : set form editor options			|
X|									|
X+----------------------------------------------------------------------*/
Xset_options (hilite, rvideo, undline, fname)
Xint	hilite;				/* highlight attribute */
Xint	rvideo;				/* reverse video attribute */
Xint	undline;			/* underline attribute */
Xchar	*fname;				/* output variable file name */
X	{
X	char		sbuf [80];	/* set mode */
X	char		ebuf [80];	/* exit mode */
X
X	ENTER(set_options);
X
X	sbuf[0] = ebuf[0] = EOS;
X	if (hilite) {
X		get_hilite (sbuf, ebuf);
X		strcat (Enter_mode, sbuf);
X		strcat (Exit_mode, ebuf);
X		}
X	if (undline) {
X		get_undline (sbuf, ebuf);
X		strcat (Enter_mode, sbuf);
X		strcat (Exit_mode, ebuf);
X		}
X	if (rvideo) {
X		get_rvideo (sbuf, ebuf);
X		strcat (Enter_mode, sbuf);
X		strcat (Exit_mode, ebuf);
X		}
X	if (fname) strncpy (Varfile, fname, MAXFNAME);
X	EXIT;
X	}
SHAR_EOF
if test 1317 -ne "`wc -c < 'option.c'`"
then
	echo shar: error transmitting "'option.c'" '(should have been 1317 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'msg.c'" '(2999 characters)'
if test -f 'msg.c'
then
	echo shar: will not over-write existing file "'msg.c'"
else
sed 's/^X//' << \SHAR_EOF > 'msg.c'
X/* Last update: 01/13/88  10:59 AM  (Edition: 11) */
X#include	<stdio.h>
X#include	<strings.h>
X#include	"basic.h"
X#include	"form.h"
X/*
X    Two flavors to display message:
X
X	form_msg	display message then  position cursor at given
X			position, this allows form filling on terminal
X			without cursor save restore capability.
X
X	formmsg		display  message and return   to  the caller's
X			position  using terminal's save/restore cursor
X			ability. This is designed to be used  by field
X			checking routine where  user don't know  where
X			the field is.
X*/
X
X#define MAXSMSG 5
X#define MSGSIZE 132
X
Xint	Form_msg = 0;			/* form message on screen flag */
X
Xstatic	char	Savemsg [MAXSMSG][MSGSIZE];
Xstatic	int	Sdx = 0;		/* number of next entry to use */
Xstatic	int	Smcount = 0;		/* number of messages saved */
X/*----------------------------------------------------------------------+
X|									|
X|	    form_msg : display message on the message line		|
X|									|
X+----------------------------------------------------------------------*/
Xform_msg (s, line, col)
Xchar		*s;		/* message to display, if NULL, clear message */
Xunsigned char	line;		/* line to go at end */
Xunsigned char	col;		/* column to go at end */
X	{
X	ENTER (form_msg);
X	poscur ((unsigned char)24, (unsigned char)1, (char *)NULL);
X	screen (SCR_REVERSE);
X	screen (SCR_EEOL);
X	if (s) {
X		Form_msg = 1;
X		put_string (s, 0);
X		save_msg (s);
X		}
X	else	Form_msg = 0;
X	poscur (line, col, (char *)NULL);
X	EXIT;
X	}
X 
X/*----------------------------------------------------------------------+
X|									|
X|	  formmsg : form_msg () use terminal SC, RC feature		|
X|									|
X+----------------------------------------------------------------------*/
Xformmsg (s)
Xchar	*s;		/* message to display, if NULL, clear message */
X	{
X	ENTER (formmsg);
X	screen (SCR_SAVE);
X	poscur ((unsigned char)24, (unsigned char)1, (char *)NULL);
X	screen (SCR_REVERSE);
X	screen (SCR_EEOL);
X	if (s) {
X		Form_msg = 1;
X		put_string (s, 0);
X		save_msg (s);
X		}
X	else	Form_msg = 0;
X	screen (SCR_RESTORE);
X	EXIT;
X	}
X 
X/*----------------------------------------------------------------------+
X|									|
X|	    save_msg : save a message on the message buffer		|
X|									|
X+----------------------------------------------------------------------*/
Xsave_msg (s)
Xchar	*s;
X	{
X	ENTER (save_msg);
X	strncpy (Savemsg[Sdx], s, MSGSIZE);
X	if (++Sdx >= MAXSMSG) Sdx = 0;
X	if (Smcount < MAXSMSG) Smcount++;
X	EXIT;
X	}
X 
X/*----------------------------------------------------------------------+
X|									|
X|	    prev_msg : display previously displayed message		|
X|									|
X+----------------------------------------------------------------------*/
Xprev_msg ()
X	{
X	ENTER (prev_msg);
X	if (!Smcount) return (0);
X	/* This routine actually pop the message stored */
X	if (--Sdx < 0) Sdx = MAXSMSG-1;
X	screen (SCR_SAVE);
X	poscur ((unsigned char)24, (unsigned char)1, (char *)NULL);
X	screen (SCR_REVERSE);
X	screen (SCR_EEOL);
X	put_string (Savemsg[Sdx], 0);
X	Form_msg = 1;
X	screen (SCR_RESTORE);
X	RETURN (1);
X	}
SHAR_EOF
if test 2999 -ne "`wc -c < 'msg.c'`"
then
	echo shar: error transmitting "'msg.c'" '(should have been 2999 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'term.c'" '(6575 characters)'
if test -f 'term.c'
then
	echo shar: will not over-write existing file "'term.c'"
else
sed 's/^X//' << \SHAR_EOF > 'term.c'
X/* Last update: 01/13/88  11:16 AM  (Edition: 9) */
X#include	<stdio.h>
X#include	<ctype.h>
X#include	<strings.h>
X#include	"form.h"
X
X#define	YES	(1)
X#define	NO	(0)
X#define	EOS	'\0'
X#define	when		break; case
X#define	otherwise	break;default
X
Xstatic	char	*Erase = "\010 \010";	/* erase string */
X
Xstruct	tcap	{
X	char		*tc_id;		/* key for capability	*/
X	char		*tc_str;	/* ptr to Tc_str area	*/
X	unsigned char	tc_delay;	/* # of msec to delay	*/
X	unsigned char	tc_len;		/* length of tc_str	*/
X	};
X
Xstatic	char	Termcap [1024];
Xstatic	char	Tstr [1024];		/* buffer for real escape sequence */
Xstatic	char	*Tsp = Tstr;		/* pointer to be used by tgetstr */
Xstatic	int	Tcap_count = 0;		/* # of entries extracted */
X
X/*-------- You may want to modify the following (also term.h) ----------*/
X#include	"term.h"
X
Xstatic	struct	tcap Tcap [] = {
X		{ "bc",	0, NULL, 0 },	/* cursor backspace		*/
X		{ "cm",	0, NULL, 0 },	/* cursor motion		*/
X		{ "cl", 0, NULL, 0 },	/* clear entire screen		*/
X		{ "cd", 0, NULL, 0 },	/* clear to end of display	*/
X		{ "ce", 0, NULL, 0 },	/* clear to end of line		*/
X		{ "ho", 0, NULL, 0 },	/* home cursor			*/
X		{ "ks", 0, NULL, 0 },	/* start keypad xmit mode	*/
X		{ "ke", 0, NULL, 0 },	/* end keypad xmit mode		*/
X		{ "ku", 0, NULL, 0 },	/* (input) cursor upper		*/
X		{ "kd", 0, NULL, 0 },	/* (input) cursor down		*/
X		{ "kl", 0, NULL, 0 },	/* (input) cursor left		*/
X		{ "kr", 0, NULL, 0 },	/* (input) cursor right		*/
X		{ "md", 0, NULL, 0 },	/* mode dim (or highlite)	*/
X		{ "me", 0, NULL, 0 },	/* mode end (return to normal)	*/
X		{ "rc", 0, NULL, 0 },	/* restore cursor		*/
X		{ "sc", 0, NULL, 0 },	/* save cursor			*/
X		{ "so", 0, NULL, 0 },	/* start reverse video mode	*/
X		{ "se", 0, NULL, 0 },	/* end				*/
X		{ "us", 0, NULL, 0 },	/* start underline mode 	*/
X		{ "ue", 0, NULL, 0 },	/* end				*/
X		{ NULL, 0, NULL, 0 }
X	};
X
Xchar	*getenv ();
Xchar	*tgetstr ();
Xchar	*tgoto ();
X
X/*-------------------------------------------------------------05/10/86-+
X|									|
X|	      tcap_init : initialize termcap data structure		|
X|									|
X+----------------------------------------------------------------------*/
Xtcap_init ()
X	{
X	struct	tcap	*p;
X	char		*tp;
X	unsigned int	delay;
X	int		status;
X	char		*termtype = getenv ("TERM");
X
X	if ((status = tgetent (Termcap, termtype)) != 1) {
X		if (status == 0) {
X			fprintf (stderr, "No entry for %s in termcap\r\n",
X				 termtype);
X			}
X		else	fprintf (stderr, "Can not open termcap file\r\n");
X		exit (1);
X		}
X
X	for (p= &Tcap[0]; p->tc_id != EOS; p++) {
X		tp = tgetstr (p-> tc_id, &Tsp);
X		if (tp == NULL) {	 /* no such capability */
X			if (p == &Tcap[BC]) tp = "\010";
X			else tp = "";
X			}
X		delay = 0;
X		while (isdigit (*tp)) {
X			delay = delay*10 + (*tp++) - '0';
X			}
X		p->tc_str = tp;
X		p->tc_delay = delay;
X		p->tc_len = strlen (tp);
X		Tcap_count++;
X		}
X	}
X
X/*----------------------------------------------------------------------+
X|									|
X|		screen : common screen operation routine		|
X|									|
X+----------------------------------------------------------------------*/
Xscreen (code)
Xint	code;		/* operation code */
X	{
X	int		n = BAD;	/* init to not valid entry */
X	struct	tcap	*te;
X
X	if (Tcap_count == 0) tcap_init ();
X	switch (code) {
X		when SCR_DEL:		put_string (Erase, 0);
X		when SCR_BACKSPACE:	n = BC;
X		when SCR_ERASE:		n = CL;
X		when SCR_HOME:		n = HO;
X		when SCR_EEOL:		n = CE;
X		when SCR_SAVE:		n = SC;
X		when SCR_KEYXMIT:	n = KS;
X		when SCR_NOKEYXMIT:	n = KE;
X		when SCR_RESTORE:	n = RC;
X		when SCR_REVERSE:	n = SO;
X		when SCR_NORMAL:	n = SE;
X		otherwise:	;	/* ignore it */
X		}
X	if (n != BAD) {
X		te = &Tcap[n];
X		delay (te-> tc_delay);
X		put_string (te-> tc_str, (unsigned)te-> tc_len);
X		}
X	}
X 
X/*----------------------------------------------------------------------+
X|									|
X|	   poscur : position cursor on line, column on screen		|
X|									|
X+----------------------------------------------------------------------*/
Xposcur (line, column, s)
Xunsigned char	line;
Xunsigned char	column;
Xchar		*s;		/* option string to output at line, column */
X	{
X	char	*p;
X
X	if (Tcap_count == 0) tcap_init ();
X	p = tgoto (Tcap[CM].tc_str, column-1, line-1);
X	delay (Tcap[CM].tc_delay);
X	put_string (p, 0);
X	if (s != NULL) put_string (s, 0);
X	}
X
X/*-------------------------------------------------------------05/10/86-+
X|									|
X|	  delay : delay output for n msec (actually write NULL)		|
X|									|
X+----------------------------------------------------------------------*/
Xstatic
Xdelay (n)
Xunsigned char	n;			/* # of msec to delay */
X	{
X	static	char	c = EOS;
X	register int	i;
X
X	if (n == 0) return;
X
X	for (i=0; i<n; i++) {
X		write (fileno (stdout), &c, 1);
X		}
X	}
X
X/*-------------------------------------------------------------05/11/86-+
X|									|
X|		  Routines to get mode-specific strings			|
X|									|
X+----------------------------------------------------------------------*/
Xget_undline (sbuf, ebuf)
Xchar	*sbuf;				/* enter mode buffer */
Xchar	*ebuf;				/* exit mode buffer */
X	{
X	if (Tcap_count == 0) tcap_init ();
X	strcpy (sbuf, Tcap[US].tc_str);
X	strcpy (ebuf, Tcap[UE].tc_str);
X	}
X
Xget_hilite (sbuf, ebuf)
Xchar	*sbuf;				/* enter mode buffer */
Xchar	*ebuf;				/* exit mode buffer */
X	{
X	if (Tcap_count == 0) tcap_init ();
X	strcpy (sbuf, Tcap[MD].tc_str);
X	strcpy (ebuf, Tcap[ME].tc_str);
X	}
X
Xget_rvideo (sbuf, ebuf)
Xchar	*sbuf;				/* enter mode buffer */
Xchar	*ebuf;				/* exit mode buffer */
X	{
X	if (Tcap_count == 0) tcap_init ();
X	strcpy (sbuf, Tcap[SO].tc_str);
X	strcpy (ebuf, Tcap[SE].tc_str);
X	}
X
X/*-------------------------------------------------------------07/05/87-+
X|									|
X|	    getkey : get user entered key (handle cursor key)		|
X|									|
X+----------------------------------------------------------------------*/
Xgetkey ()
X	{
X	char		buf[20];	/* temporary hold the input stream */
X	char		c;
X	register int	i = 0;
X	register int	ci = 0;		/* current matched index */
X	int		idx;
X	char		match;		/* flag, YES/NO */
X	char		kmatch [4];	/* record how may char matched in
X					   each key (KU, KD, KL, KR) */
X	extern char	get_char();
X
X	for (i=0; i<4; i++) kmatch[i] = 0;
Xloop:
X	c = get_char () & 0x7f;			/* make it ASCII */
X	for (match=NO, i=0; i<4; i++) {
X		if (kmatch[i] < ci) continue;
X		switch (i) {
X			when 0: idx = KU;
X			when 1: idx = KD;
X			when 2: idx = KL;
X			when 3: idx = KR;
X			}
X		if (c == Tcap[idx].tc_str[ci]) {
X			kmatch[i]++;
X			if (Tcap[idx].tc_len == ci+1) {
X				ci = 0;
X				return (0x80 | idx);
X				}
X			match = YES;
X			}
X		}
X	buf[ci++] = c;		/* save input char in temp buffer */
X	if (match == YES) goto loop;
X
X	pushback (&buf[1], ci-1);
X	return (buf[0]);
X	}
SHAR_EOF
if test 6575 -ne "`wc -c < 'term.c'`"
then
	echo shar: error transmitting "'term.c'" '(should have been 6575 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'io.c'" '(4106 characters)'
if test -f 'io.c'
then
	echo shar: will not over-write existing file "'io.c'"
else
sed 's/^X//' << \SHAR_EOF > 'io.c'
X/* Last update: 01/13/88  11:26 AM  (Edition: 5) */
X#include	<stdio.h>
X#include	<ctype.h>
X#include	<sys/file.h>
X
X#ifndef		_SGTTYB_
X#include	<sgtty.h>
X#endif
X
Xint		Term_input;
Xint		Term_output;
Xextern	int	Debug;
X/*-------------------------------------------------------------05/07/86-+
X|									|
X|	    put_string : write out a string to Term_output		|
X|									|
X+----------------------------------------------------------------------*/
Xput_string (s, len)
Xchar		*s;
Xunsigned	len;
X	{
X	if (len == 0) len = strlen (s);
X	if (Debug) {
X		register int	i;
X		register char	*p = s;
X
X		for (i=0; i<len; i++) put_char (*p++);
X		}
X	else write (Term_output, s, (int)len);
X	}
X
X/*-------------------------------------------------------------05/07/86-+
X|									|
X|	    put_char : write out one char to Term_output		|
X|									|
X+----------------------------------------------------------------------*/
Xput_char (c)
Xchar	c;
X	{
X	if (Debug) {
X		if (isprint(c)) write (Term_output, &c, 1);
X		else	{
X			char	buf [2];
X			buf[0] = (c < ' ') ? '^' : '~';
X			buf[1] = (c | 0x40) & 0x5f;
X			write (Term_output, buf, 2);
X			}
X		}
X	else write (Term_output, &c, 1);
X	}
X
Xstatic	char	Pushbuf [80];
Xstatic	int	Pushi = 0;
X/*-------------------------------------------------------------05/07/86-+
X|									|
X|		get_char : get a char from Term_input			|
X|									|
X+----------------------------------------------------------------------*/
Xchar
Xget_char ()
X	{
X	char		c;
X	register int	i;
X
X	if (Pushi > 0) {		/* push buffer not empty */
X		c = Pushbuf[0];
X		Pushi--;
X		for (i=0; i<Pushi; i++) {
X			Pushbuf[i] = Pushbuf[i+1];
X			}
X		return (c);
X		}
X	read (Term_input, &c, 1);
X	c &= 0x7f;			/* make it ASCII */
X	return (c);
X	}
X
Xpushback (buf, len)
Xchar	*buf;
Xint	len;
X	{
X	register char	*p = &Pushbuf [Pushi];
X
X	Pushi += len;
X	while (len-- > 0) {
X		*p++ = *buf++;
X		}
X	}
X
Xstatic	int		Old_flags;
Xstatic	struct	sgttyb	Mode_tty;
X/*-------------------------------------------------------------05/07/86-+
X|									|
X|		 cbreakio : enter/exit cbreak I/O mode			|
X|									|
X+----------------------------------------------------------------------*/
Xcbreakio (n)
Xint	n;				/* 1 -- enter, 0 -- exit */
X	{
X	static	int	cbreak_io = 0;
X	int		ostate;
X
X	ostate = cbreak_io;
X	if (n) {
X		if (!cbreak_io) {
X			open_tty ();
X			cbreak_io = 1;
X			}
X		}
X	else	{
X		if (cbreak_io) {
X			close_tty ();
X			cbreak_io = 0;
X			}
X		}
X	return (ostate);
X	}
X
X/*-------------------------------------------------------------01/12/88-+
X|									|
X|		term_init : open terminal for read/write		|
X|									|
X+----------------------------------------------------------------------*/
Xterm_init ()
X	{
X	extern	char	*Prgname;
X
X	if ((Term_input = open ("/dev/tty", O_RDONLY)) < 0) {
X		perror ("term_init: open(/dev/tty,r)");
X		exit (1);
X		}
X	if ((Term_output = open ("/dev/tty", O_WRONLY)) < 0) {
X		perror ("term_init: open(/dev/tty,r)");
X		exit (1);
X		}
X
X	if (!isatty(Term_input) || !isatty(Term_output)) {
X		fprintf (stderr, "You have to run %s interactively\n",
X			 Prgname);
X		exit (1);
X		}
X	}
X
X/*-------------------------------------------------------------01/12/88-+
X|									|
X|		 term_close : close terminal descriptors		|
X|									|
X+----------------------------------------------------------------------*/
Xterm_close ()
X	{
X	close (Term_input);
X	close (Term_output);
X	}
X/*------------------------------------------------------------07/10/84--+
X|									|
X|	 open_tty : open terminal in CBREAK mode without ECHO		|
X|									|
X+----------------------------------------------------------------------*/
Xstatic	open_tty ()
X	{
X	gtty (Term_input, &Mode_tty);
X	Old_flags = Mode_tty.sg_flags;		/* save old setting */
X	Mode_tty.sg_flags |= CBREAK;
X	Mode_tty.sg_flags &= ~(ECHO | CRMOD);
X	stty (Term_input, &Mode_tty);
X	}
X
X/*------------------------------------------------------------07/10/84--+
X|									|
X|	close_tty : close terminal and restore original setting		|
X|									|
X+----------------------------------------------------------------------*/
Xstatic	close_tty ()
X	{
X	Mode_tty.sg_flags = Old_flags;
X	stty (Term_input, &Mode_tty);		/* restore original setting */
X	}
SHAR_EOF
if test 4106 -ne "`wc -c < 'io.c'`"
then
	echo shar: error transmitting "'io.c'" '(should have been 4106 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'summary.c'" '(1880 characters)'
if test -f 'summary.c'
then
	echo shar: will not over-write existing file "'summary.c'"
else
sed 's/^X//' << \SHAR_EOF > 'summary.c'
X/* Last update: 01/14/88  00:30 AM  (Edition: 14) */
X#include	<stdio.h>
X#include	"basic.h"
X#include	"form.h"
X
Xstatic char	*Summary[] = {
X"    RETURN - terminate        CTRL P or up arrow - vertical up one field",
X"    TAB    - next field       CTRL N or down arrow - vertical down one field",
X"    CTRL T - prev field       Intr char - abort",
X"    CTRL L - refresh screen   Stop char - stop process",
X"",
X"--- Editable Field ---                  --- Selection Field ---",
X"  Movement:",
X"    CTRL A - beginning of field         SPACE  - show next selection",
X"    CTRL E - end of field               CTRL H - show prev selection",
X"    CTRL F - forward one char           x      - find next selection starts",
X"             or --> key                          with character 'x'",
X"    CTRL B - backword one char          ?      - get help message (-m flag)",
X"             or <-- key or CTRL H",
X"  Editing:",
X"    CTRL U - delete to start of field",
X"    CTRL K - delete to end of field",
X"    CTRL W - delete prev word",
XNULL
X};
X
Xstatic char	*Newline = "\r\n\r\n";
Xstatic char	*Header = "Shell Form Version: ";
Xextern	char	*Version;
Xextern	char	*Copyright;
Xextern	char	*Bugs;
Xextern	char	get_char();
X/*-------------------------------------------------------------01/13/88-+
X|									|
X|		 show_summary : display on-line summary 		|
X|									|
X+----------------------------------------------------------------------*/
Xshow_summary ()
X	{
X	char	**pp = Summary;
X	char	*p;
X
X	ENTER (show_summary);
X	screen (SCR_ERASE);
X	put_string (Header, 0);    put_string (Version, 0);
X	put_string (Newline, 2);
X	put_string (Copyright, 0); put_string (Newline, 2);
X	put_string (Bugs, 0);      put_string (Newline, 4);
X	while ((p = *pp++) != NULL) {
X		put_string (p, 0);
X		put_string (Newline, 2);
X		}
X	put_string ("\r\n     Press SPACE to continue: ", 0);
X	while (get_char() != ' ');
X	EXIT;
X	}
SHAR_EOF
if test 1880 -ne "`wc -c < 'summary.c'`"
then
	echo shar: error transmitting "'summary.c'" '(should have been 1880 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0

-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.