v03i035: mg 2a part 11 of 15
Bob Larson
BLARSON at ECLA.USC.EDU
Thu May 26 15:01:04 AEST 1988
comp.sources.misc: Volume 3, Issue 35
Submitted-By: "Bob Larson" <BLARSON at ECLA.USC.EDU>
Archive-Name: mg2a/Part11
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# termlib/fgetlr.c
# termlib/isdigit.c
# termlib/testtcp.c
# termlib/tgetent.c
# termlib/tgetflag.c
# termlib/tgetnum.c
# termlib/tgetstr.c
# termlib/tgoto.c
# termlib/tputs.c
# termlib/ttest.c
# This archive created: Tue May 17 21:42:47 1988
# By: blarson
if test -d termlib
then true
else mkdir termlib
fi
cat << \SHAR_EOF > termlib/fgetlr.c
/************************************************************************
* *
* Copyright (c) 1982, Fred Fish *
* All Rights Reserved *
* *
* This software and/or documentation is released for public *
* distribution for personal, non-commercial use only. *
* Limited rights to use, modify, and redistribute are hereby *
* granted for non-commercial purposes, provided that all *
* copyright notices remain intact and all changes are clearly *
* documented. The author makes no warranty of any kind with *
* respect to this product and explicitly disclaims any implied *
* warranties of merchantability or fitness for any particular *
* purpose. *
* *
************************************************************************
*/
/*
* LIBRARY FUNCTION
*
* fgetlr get logical record from a file
*
* KEY WORDS
*
* fgetlr
* string functions
*
* SYNOPSIS
*
* char *fgetlr(bp,bpsize,fp)
* char *bp;
* int bpsize;
* FILE *fp;
*
* DESCRIPTION
*
* Reads the next logical record from stream "fp" into buffer "bp"
* until next unescaped newline, "bpsize" minus one characters
* have been read, end of file, or read error.
* The last character read is followed by a NULL.
*
* A logical record may span several physical records by having
* each newline escaped with the standard C escape character
* (backslash).
*
* This is particularly useful for things like the termcap
* file, where a single entry is too long for one physical
* line, yet needs to be treated as a single record.
*
* Returns its first argument unless an end of file or read
* error occurs prior to any characters being read.
*
* BUGS
*
* The only way to know if read was terminated due to buffer size
* limitation is to test for a newline before the terminating
* null.
*
*/
#include <stdio.h>
/*
* PSEUDO CODE
*
* Begin fgetlr
* If read fails then
* Return NULL.
* Else
* Find out how many characters were read.
* Initialize pointer to terminating null.
* If last char read was newline then
* If newline was escaped then
* Replace backslash with the newline.
* Replace newline with null.
* Read and append more.
* End if
* End if
* Return buffer pointer.
* End if
* End fgetlr
*
*/
char *fgetlr(bp,bpsize,fp)
char *bp;
int bpsize;
FILE *fp;
{
int numch;
char *cp;
if (fgets(bp,bpsize,fp) == NULL) {
return(NULL);
} else {
numch = strlen(bp);
cp = &bp[numch];
if (*--cp == '\n') {
if (numch > 1 && *--cp == '\\') {
*cp++ = '\n';
*cp = NULL;
fgetlr(cp,bpsize-numch+1,fp);
}
}
return(bp);
}
}
SHAR_EOF
cat << \SHAR_EOF > termlib/isdigit.c
/************************************************************************
* *
* Copyright (c) 1982, Fred Fish *
* All Rights Reserved *
* *
* This software and/or documentation is released for public *
* distribution for personal, non-commercial use only. *
* Limited rights to use, modify, and redistribute are hereby *
* granted for non-commercial purposes, provided that all *
* copyright notices remain intact and all changes are clearly *
* documented. The author makes no warranty of any kind with *
* respect to this product and explicitly disclaims any implied *
* warranties of merchantability or fitness for any particular *
* purpose. *
* *
************************************************************************
*/
/*
* LIBRARY FUNCTION
*
* isdigit test character for numeric property
*
* SYNOPSIS
*
* int isdigit(ch)
* char ch;
*
* DESCRIPTION
*
* Returns TRUE or FALSE depending upon whether the specified
* character is a numeric character or not.
*
* BUGS
*
* May fail on machines in which native character set is not ASCII.
*
*/
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int isdigit(ch)
char ch;
{
if (ch > '9' || ch < '0') {
return(FALSE);
} else {
return(TRUE);
}
}
SHAR_EOF
cat << \SHAR_EOF > termlib/testtcp.c
/************************************************************************
* *
* Copyright (c) 1982, Fred Fish *
* All Rights Reserved *
* *
* This software and/or documentation is released for public *
* distribution for personal, non-commercial use only. *
* Limited rights to use, modify, and redistribute are hereby *
* granted for non-commercial purposes, provided that all *
* copyright notices remain intact and all changes are clearly *
* documented. The author makes no warranty of any kind with *
* respect to this product and explicitly disclaims any implied *
* warranties of merchantability or fitness for any particular *
* purpose. *
* *
************************************************************************
*/
/*
* TEST PROGRAM
*
* testtcp test termcap functions
*
* KEY WORDS
*
* test routines
* termcap test
*
* SYNOPSIS
*
* termcap [-efns] terminal [capability [capability ...]]
*
* -e => expand string capability given by -s
* -f => determine boolean capabilities for terminal
* -n => determine numeric capabilities for terminal
* -s => determine string capabilities for terminal
*
* terminal => terminal name as given in termcap file
* capability => a boolean, numeric, or string capability
*
* NOTE: All capabilities must be of same type, as
* given by [-fns].
*
* If terminal is only argument then entire entry is
* printed.
*
* DESCRIPTION
*
* Provides way to test termcap functions. Can find
* and print an entire termcap terminal entry, or various
* capabilities from the entry.
*
* AUTHOR
*
* Fred Fish
*
*/
#include <stdio.h>
#define TRUE 1
#define FALSE 0
#define NO_FILE -1 /* Returned if can't open file */
#define NO_ENTRY 0 /* Returned if can't find entry */
#define SUCCESS 1 /* Returned if entry found ok */
#define TRUNCATED 2 /* Returned if entry found but trunc */
#define BUFFER_SIZE 1024
int eflag = FALSE;
int fflag = FALSE;
int nflag = FALSE;
int sflag = FALSE;
int got_terminal = FALSE;
int got_capability = FALSE;
/*
* FUNCTION
*
* main termcap test entry point
*
* KEY WORDS
*
* main
*
* SYNOPSIS
*
* main(argc,argv)
* int argc;
* char *argv[];
*
* DESCRIPTION
*
* This is where the termcap test starts executing. All argument list
* switches are processed first, then all the specified
* capability identification strings are processed.
*
*/
/*
* PSEUDO CODE
*
* Begin main
* Process command line options.
* For each argument list field
* If field was not erased during option processing
* If terminal name field not yet processed then
* Process an assumed terminal name field.
* Set terminal name processed flag.
* Else
* Process a capability field.
* Set capability field processed flag.
* End if
* End if
* End for
* If no capabilities processed then
* Simply dump buffer.
* End if
* End main
*
*/
main(argc, argv)
int argc;
char *argv[];
{
char *argp;
int argnum;
char buffer[BUFFER_SIZE];
options(argc,argv);
for (argnum = 1; argnum < argc; argnum++) {
if ((argp = argv[argnum]) != NULL) {
if (!got_terminal) {
terminal(buffer,argp);
got_terminal = TRUE;
} else {
capability(argp);
got_capability = TRUE;
}
}
}
if (got_terminal && !got_capability) {
printf("%s",buffer);
}
}
/*
* FUNCTION
*
* options process command line options
*
* SYNOPSIS
*
* options(argc,argv)
* int argc;
* char *argv[];
*
* DESCRIPTION
*
* Scans argument list, processing each switch as it is
* found. The pointer to each switch string is then
* replaced with a NULL to effectively erase the switch
* argument.
*
*/
/*
* PSEUDO CODE
*
* Begin options
* For each argument in the argument list
* Get pointer to first char of argument.
* If the argument is a switch then
* Replace argument pointer with NULL.
* Look at next argument character.
* While there is another argument character
* Switch on the argument character
* Case "EXPAND":
* Set expand (e) flag.
* Break out of switch.
* Case "BOOLEAN":
* Set boolean (f) flag.
* Break out of switch.
* Case "NUMERIC":
* Set numeric flag.
* Break out of switch.
* Case "STRING":
* Set string flag.
* Break out of switch.
* Default:
* Abort with usage message.
* End switch
* End while
* End if
* End for
* End options
*
*/
options(argc, argv)
int argc;
char *argv[];
{
int i;
char c; /* 1st char of current command-line argument */
char *cp; /* current argument pointer */
for (i=1; i<argc; i++) {
cp = argv[i];
if (*cp == '-') {
argv[i] = NULL;
cp++;
while (c = *cp++) {
switch (c) {
case 'e':
eflag = TRUE;
break;
case 'f':
fflag = TRUE;
break;
case 'n':
nflag = TRUE;
break;
case 's':
sflag = TRUE;
break;
default:
usage();
}
}
}
}
}
/*
* FUNCTION
*
* usage give usage message and abort
*
* KEY WORDS
*
* usage
* help processing
* abort locations
*
* SYNOPSIS
*
* usage()
*
* DESCRIPTION
*
* Usage is typically called when a problem has been
* detected in the argument list.
* It prints a usage message and exits.
*
*/
/*
* PSEUDO CODE
*
* Begin usage
* Print usage message.
* Exit.
* End usage
*
*/
usage()
{
printf("Usage: termcap [-fns] terminal [capability [capability ... ]]\n");
exit();
}
terminal(buffer,name)
char *buffer;
char *name;
{
int status;
status = tgetent(buffer,name);
switch (status) {
case NO_FILE:
fprintf(stderr,"Can't find a termcap data base file.\n");
exit();
case NO_ENTRY:
fprintf(stderr,"Can't find entry \"%s\"\n",name);
exit();
case TRUNCATED:
fprintf(stderr,"Warning --- entry \"%s\" too long\n",name);
break;
case SUCCESS:
break;
default:
fprintf(stderr,"? tgetent returned illegal status %d\n",status);
exit();
}
}
capability(id)
char *id;
{
int value;
char buffer[256];
char *area;
char *ep, *tgoto();
if (fflag) {
value = tgetflag(id);
if (value) {
printf("%s TRUE\n",id);
} else {
printf("%s FALSE\n",id);
}
} else if (nflag) {
value = tgetnum(id);
printf("%s = %o octal %d decimal\n",id,value,value);
} else if (sflag) {
area = buffer;
tgetstr(id,&area);
if (eflag) {
ep = tgoto(buffer,75,23);
}
doprint(id,buffer);
if (eflag) {
doprint(id,ep);
ep = tgoto(buffer,1,2);
doprint(id,ep);
}
}
}
doprint(id,cp)
char *id;
char *cp;
{
printf("%s = \"",id);
for ( ; *cp != NULL; cp++) {
if (*cp < 040) {
printf("^%c",*cp |= 0100);
} else {
printf("%c",*cp);
}
}
printf("\"\n");
}
SHAR_EOF
cat << \SHAR_EOF > termlib/tgetent.c
/************************************************************************
* *
* Copyright (c) 1982, Fred Fish *
* All Rights Reserved *
* *
* This software and/or documentation is released for public *
* distribution for personal, non-commercial use only. *
* Limited rights to use, modify, and redistribute are hereby *
* granted for non-commercial purposes, provided that all *
* copyright notices remain intact and all changes are clearly *
* documented. The author makes no warranty of any kind with *
* respect to this product and explicitly disclaims any implied *
* warranties of merchantability or fitness for any particular *
* purpose. *
* *
************************************************************************
*/
/*
* Modified:
* 30-Apr-86 Mic Kaczmarczik ...!ihnp4!seismo!ut-sally!ut-ngp!mic
* Instead of using VAX C getenv("TERM"), which does not
* return the value of logical name "TERM", translate the
* logical name by hand.
* 11-Oct-86 Mic Kaczmarczik ...!ihnp4!seismo!ut-sally!ut-ngp!mic
* Support tc capability to allow the library to use standard
* termcaps. Rewrote tgetent to look for tc capability
* and add new terminal definition to the caller's buffer.
* This makes it rather possible to overflow the caller's
* buffer, but the library doesn't make any claim that it
* won't overwrite the buffer anyway...
* 27-Jan-88 Bob Larson blarson at ecla.usc.edu
* Add primos (__50SERIES) support.
* 1-Feb-88 Sandra Loosemore (sandra at cs.utah.edu)
* Change default termcap file for VMS to be the same place
* that GNU puts it.
* 23-Apr-88 Bob Larson
* merge primos and vms changes
*/
/*
* LIBRARY FUNCTION
*
* tgetent load buffer with entry for specified terminal
*
* KEY WORDS
*
* termcap functions
* utility routines
*
* SYNOPSIS
*
* int tgetent(bp,name)
* char *bp;
* char *name;
*
* DESCRIPTION
*
* Extracts the entry for terminal <name> from the termcap file
* and places it in the character buffer <bp>. It is currently
* assumed that bp is at least 1024 characters. If the entry in
* the termcap file is larger than 1023 characters the excess
* characters will be discarded and appropriate status will
* be returned.
*
* Also note that since bp is used by other termcap
* routines, the storage associated with the termcap entry
* cannot be freed until all termcap calls are completed.
*
* Tgetent can be directed to look in a file other than
* the default (/etc/termcap) by defining an environment
* variable called TERMCAP to be the pathname of the desired
* termcap file. This is useful for debugging new entries.
* NOTE: the pathname MUST begin with a '/' character.
*
* Also, if the string assigned to TERMCAP does not begin with
* a '/' and if the environment variable TERM matches <name> then
* the string assigned to TERMCAP is copied to buffer <bp>
* instead of reading a termcap file.
*
* RETURNS
*
* -1 if the termcap file cannot be opened
* 0 if no entry in termcap file matches <name>
* 1 if extraction is successful with no errors
* 2 if extraction is successful but entry truncated
*
* SEE ALSO
*
* tgetnum extract numeric type capability
* tgetflag test boolean type capability
* tgetstr get string value of capability
*
* AUTHOR
*
* Fred Fish
*
*/
#include <stdio.h>
#define TRUE 1
#define FALSE 0
#define BUFSIZE 1024 /* Assumed size of external buffer */
#define NO_FILE -1 /* Returned if can't open file */
#define NO_ENTRY 0 /* Returned if can't find entry */
#define SUCCESS 1 /* Returned if entry found ok */
#define TRUNCATED 2 /* Returned if entry found but trunc */
#ifdef __50SERIES
#define DEFAULT_FILE "mg*>termcap"
#else
#define DEFAULT_FILE "/etc/termcap" /* default termcap filename */
#ifdef VAXC
#define index strchr
#endif
#endif
char *_tcpbuf; /* Place to remember buffer pointer */
FILE *fp; /* Termcap file */
static FILE *find_file();
extern char *index();
/*
* PSEUDO CODE
*
* Begin tgetent
* Erase any previous buffer contents.
* Remember the buffer pointer.
* If termcap file is not found then
* If buffer was filled anyway then
* Return SUCCESS.
* Else
* Return NO_FILE.
* End if
* Else
* Find entry associated with name
* While an entry was found and limit not reached
* If no tc capability found Then
* Exit while loop with status = SUCCESS
* Else
* Call getent to get entry indicated by tc=
* If entry not found then
* Exit loop with status != SUCCESS
* End if
* Concatenate entry into buffer
* End If
* End while
* End if
* Close termcap file
* Return status code
* End tgetent
*
*/
static int getent();
int tgetent(bp,name)
char *bp;
char *name;
{
char *tc, *tcbufp, tcbuf[80], termbuf[BUFSIZE], *tgetstr();
char *bufp, *cp; /* current start of buffer */
int limit = 10; /* maximum nesting */
int status; /* return from getent() */
*bp = '\0'; /* clear buffer */
_tcpbuf = bp; /* save base of buffer */
/* Look for termcap file. If NULL, find_file may have found a */
/* a valid termcap string in the environment variable TERMCAP. */
/* If non-null, attempt to find the entry in the termcap file */
if ((fp = find_file(bp)) == NULL) {
if (*bp != NULL)
return(SUCCESS);
else
return(NO_FILE);
}
status = getent(bp, name);/* look for main entry */
/* Start looking for tc capabilities in the termcap. If
* found, concatenate the entry for the new terminal to the
* current buffer and try again. To avoid infinite loops,
* allow only 10 loops through this process.
*/
while ((status == SUCCESS) && limit--) {
/* look for tc capability. If none found, exit loop */
tcbufp = tcbuf;
if (((tc = tgetstr("tc",&tcbufp)) == NULL)
|| (*tc == '\0')) {
status = SUCCESS;/* no more tc= entries */
break;
}
/* Attempt to get next entry. Exit loop if unsuccessful */
if ((status = getent(termbuf, tcbuf)) != SUCCESS)
break;
/* Copy new entry into buffer, right at "tc=" */
for (bufp = bp; *bufp; bufp++) /* find tc= */
if ((*bufp=='t') && (bufp[1]=='c') && (bufp[2]=='='))
break;
if ((cp = index(termbuf,':')) == NULL)
cp = termbuf;
strcpy(bufp, cp + 1);
}
/* close termcap file and return the status */
fclose(fp);
return status;
}
/*
* INTERNAL FUNCTION
*
* getent find termcap entry in termcap file
*
* KEY WORDS
*
* internal functions
* getent
*
* SYNOPSIS
*
* static int getent(bp,name)
* char *bp;
* char *name;
*
* DESCRIPTION
*
* Getent is called by tgetent each time tgetent attempts to
* read a capability from the termcap database file. Places
* the entry in the buffer pointed to by bp
*
*
* PSEUDOCODE
*
* Begin Getent
* Seek to beginning of termcap file
* Clear buffer
* While records left to process
* If this is entry is what we want then
* If entry was truncated then
* Return TRUNCATED status
* Else
* Return SUCCESS status.
* End if
* End if
* End while
* Return NO_ENTRY status.
* End
*/
static int getent(bp,name)
char *bp; /* Pointer to buffer (1024 char min) */
char *name; /* Pointer to terminal entry to find */
{
*bp = '\0'; /* clear buffer */
lseek(fileno(fp), 0L, 0l); /* rewind termcap file */
while (fgetlr(bp,BUFSIZE,fp)) {
if (gotcha(bp,name)) {
if (bp[strlen(bp)-1] != '\n') {
return(TRUNCATED);
} else {
return(SUCCESS);
}
}
}
return(NO_ENTRY);
}
/*
* INTERNAL FUNCTION
*
* find_file find the termcap file and open it if possible
*
* KEY WORDS
*
* internal functions
* find_file
*
* SYNOPSIS
*
* static FILE *find_file(bp)
* char *bp;
*
* DESCRIPTION
*
* Attempts to locate and open the termcap file. Also handles
* using the environment TERMCAP string as the actual buffer
* (that's why bp has to be an input parameter).
*
* If TERMCAP is defined an begins with a '/' character then
* it is taken to be the pathname of the termcap file and
* an attempt is made to open it. If this fails then
* the default termcap file is used instead.
*
* If TERMCAP is defined but does not begin with a '/' then
* it is assumed to be the actual buffer contents provided
* that <name> matches the environment variable TERM.
*
* BUGS
*
* There is currently no way to be sure which termcap
* file was opened since the default will always be
* tried.
*
*/
/*
* PSEUDO CODE
*
* Begin find_file
* If there is a TERMCAP environment string then
* If the string is not null then
* If the string is a pathname then
* If that file is opened successfully then
* Return its pointer.
* End if
* Else
* If there is a TERM environment string then
* If TERM matches <name> then
* Copy TERMCAP string to buffer.
* Return NULL for no file.
* End if
* End if
* End if
* End if
* End if
* Open default termcap file and return results.
* End find_file
*
*/
#ifdef __50SERIES
static FILE *find_file(bp)
char *bp;
{
char *cp;
char *gvget();
if((cp = gvget(".TERMCAP")) != NULL && *cp)
return fopen(cp, "r");
if((cp = gvget(".TERMCAP$")) != NULL && *cp)
return fopen(cp, "r");
return fopen(DEFAULT_FILE, "r");
}
#else
#ifdef VAXC
char *trnlnm();
#endif
static FILE *find_file(bp)
char *bp;
{
FILE *fp, *fopen();
char *cp, *ncp, *getenv(), vmsname[132];
if ((cp = getenv("TERMCAP")) != NULL) {
if (*cp != NULL) {
if (*cp == '/') {
if ((fp = fopen(cp,"r")) != NULL) {
return(fp);
}
} else {
#ifdef VAXC
if ((ncp = trnlnm("TERM")) != NULL) {
#else
if ((ncp = getenv("TERM")) != NULL) {
#endif
if (strcmp(cp,ncp) == 0) {
strcpy(bp,cp);
return((FILE *)NULL);
}
}
}
}
}
#ifdef VAXC
if ((fp = fopen("emacs_library:[etc]termcap.dat","r")) != NULL)
return(fp);
#endif
return(fopen(DEFAULT_FILE,"r"));
}
#endif /* __50SERIES */
/*
* INTERNAL FUNCTION
*
* gotcha test to see if entry is for specified terminal
*
* SYNOPSIS
*
* gotcha(bp,name)
* char *bp;
* char *name;
*
* DESCRIPTION
*
* Tests to see if the entry in buffer bp matches the terminal
* specified by name. Returns TRUE if match is detected, FALSE
* otherwise.
*
*/
/*
* PSEUDO CODE
*
* Begin gotcha
* If buffer character is comment character then
* Return FALSE since remainder is comment
* Else
* Initialize name scan pointer.
* Compare name and buffer until end or mismatch.
* If valid terminators for both name and buffer strings
* Return TRUE since a match was found.
* Else
* Find next non-name character in buffer.
* If not an alternate name separater character
* Return FALSE since no more names to check.
* Else
* Test next name and return results.
* End if
* End if
* End if
* End gotcha
*
*/
gotcha(bp,name)
char *bp;
char *name;
{
char *np;
if (*bp == '#') {
return(FALSE);
} else {
np = name;
while (*np == *bp && *np != NULL) {np++; bp++;}
if (*np == NULL && (*bp == NULL || *bp == '|' || *bp == ':')) {
return(TRUE);
} else {
while (*bp != NULL && *bp != ':' && *bp != '|') {bp++;}
if (*bp != '|') {
return(FALSE);
} else {
return(gotcha(++bp,name));
}
}
}
}
SHAR_EOF
cat << \SHAR_EOF > termlib/tgetflag.c
/************************************************************************
* *
* Copyright (c) 1982, Fred Fish *
* All Rights Reserved *
* *
* This software and/or documentation is released for public *
* distribution for personal, non-commercial use only. *
* Limited rights to use, modify, and redistribute are hereby *
* granted for non-commercial purposes, provided that all *
* copyright notices remain intact and all changes are clearly *
* documented. The author makes no warranty of any kind with *
* respect to this product and explicitly disclaims any implied *
* warranties of merchantability or fitness for any particular *
* purpose. *
* *
************************************************************************
*/
/*
* Modified:
* 30-Apr-86 Mic Kaczmarczik
* #define index to strchr if VAX C
*
*/
/*
* LIBRARY FUNCTION
*
* tgetflag extract boolean termcap capability
*
* KEY WORDS
*
* termcap
*
* SYNOPSIS
*
* tgetflag(id)
* char *id;
*
* DESCRIPTION
*
* Returns TRUE if specified id is present in terminal
* entry, FALSE otherwise.
*
*/
#include <stdio.h>
#ifdef VAXC
#define index strchr
#endif
#define TRUE 1
#define FALSE 0
extern char *_tcpbuf; /* Termcap entry buffer pointer */
/*
* PSEUDO CODE
*
* Begin tgetflag
* Initialize pointer to the termcap entry buffer.
* While there is a field to process
* Skip over the field separator character.
* If this is the entry we want then
* If entry is identifier only then
* Return TRUE
* Else
* Return FALSE
* End if
* End if
* End while
* Return FALSE as default.
* End tgetflag
*
*/
tgetflag(id)
char *id;
{
char *bp;
extern char *index();
bp = _tcpbuf;
while ((bp = index(bp,':')) != NULL) {
bp++;
if (*bp++ == id[0] && *bp != NULL && *bp++ == id[1]) {
if (*bp == NULL || *bp++ == ':') {
return(TRUE);
} else {
return(FALSE);
}
}
}
return(FALSE);
}
SHAR_EOF
cat << \SHAR_EOF > termlib/tgetnum.c
/************************************************************************
* *
* Copyright (c) 1982, Fred Fish *
* All Rights Reserved *
* *
* This software and/or documentation is released for public *
* distribution for personal, non-commercial use only. *
* Limited rights to use, modify, and redistribute are hereby *
* granted for non-commercial purposes, provided that all *
* copyright notices remain intact and all changes are clearly *
* documented. The author makes no warranty of any kind with *
* respect to this product and explicitly disclaims any implied *
* warranties of merchantability or fitness for any particular *
* purpose. *
* *
************************************************************************
*/
/* Modified:
* 30-Apr-86 Mic Kaczmarczik
* Use ctype.h macros instead of the function isdigit().
* #define index to strchr if VAXC
*/
/*
* LIBRARY FUNCTION
*
* tgetnum extract numeric option from termcap entry
*
* KEY WORDS
*
* termcap
* ce functions
*
* SYNOPSIS
*
* tgetnum(id)
* char *id;
*
* DESCRIPTION
*
* Returns numeric value of capability <id>, or -1 if <id>
* is not found. Knows about octal numbers, which
* begin with 0.
*
*/
#include <stdio.h>
#include <ctype.h>
#ifdef VAXC
#define index strchr
#endif
extern char *_tcpbuf; /* Termcap entry buffer pointer */
/*
* PSEUDO CODE
*
* Begin tgetnum
* Initialize pointer to the termcap entry buffer.
* While there is a field to process
* Skip over the field separator character.
* If this is the entry we want then
* If the entry is not a numeric then
* Return failure value.
* Else
* Initialize value to zero.
* If number begins with zero then
* Set accumulation base to 8.
* Else
* Set accumulation base to 10.
* End if
* While there is a numeric character
* Accumulate the value.
* End while
* Return value.
* End if
* End if
* End while
* Return failure value.
* End tgetnum
*
*/
tgetnum(id)
char *id;
{
int value, base;
char *bp;
extern char *index();
bp = _tcpbuf;
while ((bp = index(bp,':')) != NULL) {
bp++;
if (*bp++ == id[0] && *bp != NULL && *bp++ == id[1]) {
if (*bp != NULL && *bp++ != '#') {
return(-1);
} else {
value = 0;
if (*bp == '0') {
base = 8;
} else {
base = 10;
}
while (isdigit(*bp)) {
value *= base;
value += (*bp++ - '0');
}
return(value);
}
}
}
return(-1);
}
SHAR_EOF
cat << \SHAR_EOF > termlib/tgetstr.c
/************************************************************************
* *
* Copyright (c) 1982, Fred Fish *
* All Rights Reserved *
* *
* This software and/or documentation is released for public *
* distribution for personal, non-commercial use only. *
* Limited rights to use, modify, and redistribute are hereby *
* granted for non-commercial purposes, provided that all *
* copyright notices remain intact and all changes are clearly *
* documented. The author makes no warranty of any kind with *
* respect to this product and explicitly disclaims any implied *
* warranties of merchantability or fitness for any particular *
* purpose. *
* *
************************************************************************
*/
/* Modified:
* 30-Apr-86 Mic Kaczmarczik
* Use ctype.h macros instead of the function isdigit().
* #define index() to be strchr() if VAX C
*/
/*
* LIBRARY FUNCTION
*
* tgetstr extract string capability from termcap entry
*
* KEY WORDS
*
* termcap
*
* SYNOPSIS
*
* char *tgetstr(id,area)
* char *id;
* char **area;
*
* DESCRIPTION
*
* Gets the string capability for <id>, placing it in
* the buffer at *area, and advancing *area to point
* to next available storage.
*
* For example, if the following capabilities are
* in the termcap file:
*
* ZZ=zzzz
* YY=yyyyyy
* WW=www
*
* then successive calls using YY, ZZ, and WW will
* build the following buffer:
*
* yyyyyy0zzzz0www0
*
* The first call will return a pointer to yyyyyy, the
* second will return a pointer to zzzz and the third
* will return a pointer to www. Note that each
* string is null terminated, as are all C strings.
*
* Characters preceded by the carot character (\136)
* are mapped into the corresponding control character.
* For example, the two character sequence ^A becomes
* a single control-A (\001) character.
*
* The escape character is the normal C backslash and
* the normal C escape sequences are recognized, along
* with a special sequence for the ASCII escape character
* (\033). The recognized sequences are:
*
* \E => '\033' (ASCII escape character)
* \b => '\010' (ASCII backspace character)
* \f => '\014' (ASCII form feed character)
* \n => '\012' (ASCII newline/linefeed char)
* \r => '\015' (ASCII carriage return char)
* \t => '\011' (ASCII tab character)
* \ddd => '\ddd' (arbitrary ASCII digit)
* \x => 'x' (ordinary ASCII character)
*
*/
#include <stdio.h>
#include <ctype.h>
#ifdef VAXC
#define index strchr
#endif
extern char *_tcpbuf; /* Termcap entry buffer pointer */
/*
* PSEUDO CODE
*
* Begin tgetstr
* Initialize pointer to the termcap entry buffer.
* While there is a field to process
* Skip over the field separator character.
* If this is the entry we want then
* If the entry is not a string then
* Return NULL.
* Else
* Transfer string and rtn pointer.
* End if
* End if
* End while
* Return NULL
* End tgetstr
*
*/
char *tgetstr(id,area)
char *id;
char **area;
{
char *bp;
extern char *index();
static char *decode();
bp = _tcpbuf;
while ((bp = index(bp,':')) != NULL) {
if (*++bp == NULL)
break;
if (*bp++ == id[0] && *bp != NULL && *bp++ == id[1]) {
if (*bp != NULL && *bp++ != '=') {
return(NULL);
} else {
return(decode(bp,area));
}
}
}
**area = NULL;
bp = (*area)++;
return(bp);
}
/*
* INTERNAL FUNCTION
*
* decode transfer string capability, decoding escapes
*
* SYNOPSIS
*
* static char *decode(bp,area)
* char *bp;
* char **area;
*
* DESCRIPTION
*
* Transfers the string capability, up to the next ':'
* character, or null, to the buffer pointed to by
* the pointer in *area. Note that the initial
* value of *area and *area is updated to point
* to the next available location after the null
* terminating the transfered string.
*
* BUGS
*
* There is no overflow checking done on the destination
* buffer, so it better be large enough to hold
* all expected strings.
*
*/
/*
* PSEUDO CODE
*
* Begin decode
* Initialize the transfer pointer.
* While there is an input character left to process
* Switch on input character
* Case ESCAPE:
* Decode and xfer the escaped sequence.
* Break
* Case CONTROLIFY:
* Controlify and xfer the next character.
* Advance the buffer pointer.
* Break
* Default:
* Xfer a normal character.
* End switch
* End while
* Null terminate the output string.
* Remember where the output string starts.
* Update the output buffer pointer.
* Return pointer to the output string.
* End decode
*
*/
static char *decode(bp,area)
char *bp;
char **area;
{
char *cp, *bgn;
char *do_esc();
cp = *area;
while (*bp != NULL && *bp != ':') {
switch(*bp) {
case '\\':
bp = do_esc(cp++,++bp);
break;
case '^':
*cp++ = *++bp & 037;
bp++;
break;
default:
*cp++ = *bp++;
break;
}
}
*cp++ = NULL;
bgn = *area;
*area = cp;
return(bgn);
}
/*
* INTERNAL FUNCTION
*
* do_esc process an escaped sequence
*
* SYNOPSIS
*
* char *do_esc(out,in);
* char *out;
* char *in;
*
* DESCRIPTION
*
* Processes an escape sequence pointed to by
* in, transfering it to location pointed to
* by out, and updating the pointer to in.
*
*/
/*
* PSEUDO CODE
*
* Begin do_esc
* If the first character is not a NULL then
* If is a digit then
* Set value to zero.
* For up to 3 digits
* Accumulate the sum.
* End for
* Transfer the sum.
* Else if character is in remap list then
* Transfer the remapped character.
* Advance the input pointer once.
* Else
* Simply transfer the character.
* End if
* End if
* Return updated input pointer.
* End do_esc
*
*/
static char *maplist = {
"E\033b\bf\fn\nr\rt\t"
};
char *do_esc(out,in)
char *out;
char *in;
{
int count;
char ch;
extern char *index();
char *cp;
if (*in != NULL) {
if (isdigit(*in)) {
ch = 0;
for (count = 0; count < 3 && isdigit(*in); in++) {
ch <<= 3;
ch |= (*in - '0');
}
*out++ = ch;
} else if ((cp = index(maplist,*in)) != NULL) {
*out++ = *++cp;
in++;
} else {
*out++ = *in++;
}
}
return(in);
}
SHAR_EOF
cat << \SHAR_EOF > termlib/tgoto.c
/************************************************************************
* *
* Copyright (c) 1982, Fred Fish *
* All Rights Reserved *
* *
* This software and/or documentation is released for public *
* distribution for personal, non-commercial use only. *
* Limited rights to use, modify, and redistribute are hereby *
* granted for non-commercial purposes, provided that all *
* copyright notices remain intact and all changes are clearly *
* documented. The author makes no warranty of any kind with *
* respect to this product and explicitly disclaims any implied *
* warranties of merchantability or fitness for any particular *
* purpose. *
* *
************************************************************************
*/
/*
* Modified:
* 1 May 86 ...!ihnp4!ut-sally!ut-ngp!mic
* Now forces a '\0' at end of tgoto string. Tgoto wasn't,
* and this screwed up VT100-style (i.e. variable) cursor
* addressing.
*/
/*
* LIBRARY FUNCTION
*
* tgoto expand cursor addressing string from cm capability
*
* KEY WORDS
*
* termcap
*
* SYNOPSIS
*
* char *tgoto(cm,destcol,destline)
* char *cm;
* int destcol;
* int destline;
*
* DESCRIPTION
*
* Returns cursor addressing string, decoded from the cm
* capability string, to move cursor to column destcol on
* line destline.
*
* The following sequences uses one input argument, either
* line or column, and place the appropriate substitution
* in the output string:
*
* %d substitute decimal value (in ASCII)
* %2 like %d but forces field width to 2
* %3 like %d but forces field width to 3
* %. like %c
* %+x like %c but adds ASCII value of x
*
* The following sequences cause processing modifications
* but do not "use up" one of the arguments. If they
* act on an argument they act on the next one to
* be converted.
*
* %>xy if next value to be converted is
* greater than value of ASCII char x
* then add value of ASCII char y.
* %r reverse substitution of line
* and column (line is substituted
* first by default).
* %i causes input values destcol and
* destline to be incremented.
* %% gives single % character in output.
*
* BUGS
*
* Does not implement some of the more arcane sequences for
* radically weird terminals (specifically %n, %B, & %D).
* If you have one of these you deserve whatever happens.
*
*/
/*
* Miscellaneous stuff
*/
#include <stdio.h>
#define MAXARGS 2
static char *in; /* Internal copy of input string pointer */
static char *out; /* Pointer to output array */
static int args[MAXARGS]; /* Maximum number of args to convert */
static int pcount; /* Count of args processed */
static char output[64]; /* Converted string */
/*
* PSEUDO CODE
*
* Begin tgoto
* If no string to process then
* Return pointer to error string.
* Else
* Initialize pointer to input string.
* Initialize pointer to result string.
* First arg is line number by default.
* Second arg is col number by default.
* No arguments processed yet.
* While there is another character to process
* If character is a not a % character then
* Simply copy to output.
* Else
* Process the control sequence.
* End if
* End while
* Return pointer to static output string.
* End if
* End tgoto
*
*/
char *tgoto(cm,destcol,destline)
char *cm;
int destcol;
int destline;
{
static int process();
if (cm == NULL) {
return("OOPS");
} else {
in = cm;
out = output;
args[0] = destline;
args[1] = destcol;
pcount = 0;
while (*in != NULL) {
if (*in != '%') {
*out++ = *in++;
} else {
process();
}
}
*out = NULL; /* Just to make sure */
return(output);
}
}
/*
* INTERNAL FUNCTION
*
* process process the conversion/command sequence
*
* SYNOPSIS
*
* static process()
*
* DESCRIPTION
*
* Processes the sequence beginning with the % character.
* Directly manipulates the input string pointer, the
* output string pointer, and the arguments. Leaves
* the input string pointer pointing to the next character
* to be processed, and the output string pointer pointing
* to the next output location. If conversion of
* one of the numeric arguments occurs, then the pcount
* is incremented.
*
*/
/*
* PSEUDO CODE
*
* Begin process
* Skip over the % character.
* Switch on next character after %
* Case 'd':
* Process %d type conversion (variable width).
* Reinitialize output pointer.
* Break;
* Case '2':
* Process %d type conversion (width 2).
* Reinitialize output pointer.
* Break;
* Case '3':
* Process %d type conversion (width 3).
* Reinitialize output pointer.
* Break;
* Case '.'
* Process %c type conversion.
* Break;
* Case '+':
* Process %c type conversion with offset.
* Break;
* Case '>':
* Process argument modification.
* Break;
* Case 'r':
* Process argument reversal.
* Break;
* Case 'i':
* Increment argument values.
* Break;
* Case '%':
* Copy to output, incrementing pointers.
* Break;
* End switch
* End process
*
*/
static process()
{
int temp;
in++;
switch(*in++) {
case 'd':
sprintf(out,"%d",args[pcount++]);
out = &output[strlen(output)];
break;
case '2':
sprintf(out,"%02d",args[pcount++]);
out = &output[strlen(output)];
break;
case '3':
sprintf(out,"%03d",args[pcount++]);
out = &output[strlen(output)];
break;
case '.':
*out++ = args[pcount++];
break;
case '+':
*out++ = args[pcount++] + *in++;
break;
case '>':
if (args[pcount] > *in++) {
args[pcount] += *in++;
} else {
in++;
}
break;
case 'r':
temp = args[pcount];
args[pcount] = args[pcount+1];
args[pcount+1] = temp;
break;
case 'i':
args[pcount]++;
args[pcount+1]++;
break;
case '%':
*out++ = '%';
break;
}
}
SHAR_EOF
cat << \SHAR_EOF > termlib/tputs.c
/************************************************************************
* *
* Copyright (c) 1982, Fred Fish *
* All Rights Reserved *
* *
* This software and/or documentation is released for public *
* distribution for personal, non-commercial use only. *
* Limited rights to use, modify, and redistribute are hereby *
* granted for non-commercial purposes, provided that all *
* copyright notices remain intact and all changes are clearly *
* documented. The author makes no warranty of any kind with *
* respect to this product and explicitly disclaims any implied *
* warranties of merchantability or fitness for any particular *
* purpose. *
* *
************************************************************************
*/
/* Modified:
* 30-Apr-86 Mic Kaczmarczik
* - Use ctype.h macros instead of the function isdigit().
* - Use VMS speed value for ospeed -- in microEmacs
* this is obtainted by ttinit().
*/
/*
* LIBRARY FUNCTION
*
* tputs output string with appropriate padding
*
* KEY WORDS
*
* termcap
*
* SYNOPSIS
*
* tputs(cp,affcnt,outc)
* char *cp;
* int affcnt;
* int (*outc)();
*
* DESCRIPTION
*
* Outputs string pointed to by cp, using function outc, and
* following it with the appropriate number of padding characters.
* Affcnt contains the number of lines affected, which is used
* as a multiplier for the specified per line pad time. If
* per line pad count is not applicable, affcnt should be 1,
* NOT zero.
*
* The format of the string pointed to by cp is:
*
* [pad time][*]<string to send>
*
* where: pad time => time to delay in milliseconds
* * => specifies that time is per line
*
* The pad character is assumed to reside in the external
* variable "PC". Also, the external variable "ospeed"
* should contain the output speed of the terminal as
* encoded in /usr/include/sgtty.h (B0-B9600).
*
* SYSTEM DEPENDENCIES
*
* On VMS, the external variable "ospeed" should contain the
* output speed of the terminal as obtained from byte 3 of
* the iosb status buffer, using the IO$_SENSEMODE QIO.
* The table times[] compiles into the correct values for VMS,
* and, happily, also handles 19200 baud.
*
* BUGS
*
* If ospeed is 0 for some reason, there is the chance of a
* divide by 0 operation.
*
*/
/*
* Miscellaneous stuff
*/
#include <stdio.h>
#include <ctype.h>
extern char PC; /* Pad character to use */
extern short ospeed; /* Encoding of output speed */
#if VMS
static int times[] = {
10000, /* Tenths of ms per char 0 baud (bogus) */
2000, /* Tenths of ms per char 50 baud */
1333, /* Tenths of ms per char 75 baud */
909, /* Tenths of ms per char 110 baud */
743, /* Tenths of ms per char 134 baud */
666, /* Tenths of ms per char 150 baud */
333, /* Tenths of ms per char 300 baud */
166, /* Tenths of ms per char 600 baud */
83, /* Tenths of ms per char 1200 baud */
55, /* Tenths of ms per char 1800 baud */
50, /* Tenths of ms per char 2000 baud */
41, /* Tenths of ms per char 2400 baud */
28, /* Tenths of ms per char 3600 baud */
20, /* Tenths of ms per char 4800 baud */
14, /* Tenths of ms per char 7200 baud */
10, /* Tenths of ms per char 9600 baud */
5 /* Tenths of ms per char 19200 baud */
};
#else
/* Times for Unix */
static int times[] = {
0, /* Tenths of ms per char 0 baud */
2000, /* Tenths of ms per char 50 baud */
1333, /* Tenths of ms per char 75 baud */
909, /* Tenths of ms per char 110 baud */
743, /* Tenths of ms per char 134 baud */
666, /* Tenths of ms per char 150 baud */
500, /* Tenths of ms per char 200 baud */
333, /* Tenths of ms per char 300 baud */
166, /* Tenths of ms per char 600 baud */
83, /* Tenths of ms per char 1200 baud */
55, /* Tenths of ms per char 1800 baud */
41, /* Tenths of ms per char 2400 baud */
20, /* Tenths of ms per char 4800 baud */
10 /* Tenths of ms per char 9600 baud */
};
#endif
/*
* PSEUDO CODE
*
* Begin tgoto
* If string pointer is invalid then
* Return without doing anything.
* Else
* For each pad digit (if any)
* Do decimal left shift.
* Accumulate the lower digit.
* End for
* Adjust scale to tenths of milliseconds
* If there is a fractional field
* Skip the decimal point.
* If there is a valid tenths digit
* Accumulate the tenths.
* End if
* Discard remaining digits.
* End if
* If per line is specified then
* Adjust the pad time.
* Discard the per line flag char.
* End if
* While there are any characters left
* Send them out via output function.
* End while
* Transmit any padding required.
* End if
* End tgoto
*
*/
tputs(cp,affcnt,outc)
char *cp;
int affcnt;
int (*outc)();
{
int ptime; /* Pad time in tenths of milliseconds */
static do_padding();
if (cp == NULL || *cp == NULL) {
return;
} else {
for (ptime = 0; isdigit(*cp); cp++) {
ptime *= 10;
ptime += (*cp - '0');
}
ptime *= 10;
if (*cp == '.') {
cp++;
if (isdigit(*cp)) {
ptime += (*cp++ - '0');
}
while (isdigit(*cp)) {cp++;}
}
if (*cp == '*') {
ptime *= affcnt;
cp++;
}
while (*cp != NULL) {
(*outc)(*cp++);
}
do_padding(ptime,outc);
}
}
/*
* FUNCTION
*
* do_padding transmit any pad characters required
*
* SYNOPSIS
*
* static do_padding(ptime,outc)
* int ptime;
* int (*outc)();
*
* DESCRIPTION
*
* Does any padding required as specified by ptime (in tenths
* of milliseconds), the output speed given in the external
* variable ospeed, and the pad character given in the
* external variable PC.
*
*/
/*
* PSEUDO CODE
*
* Begin do_padding
* If there is a non-zero pad time then
* If the external speed is in range then
* Look up the delay per pad character.
* Round pad time up by half a character.
* Compute number of characters to send.
* For each pad character to send
* Transmit the pad character.
* End for
* End if
* End if
* End do_padding
*
*/
static do_padding(ptime,outc)
int ptime;
int (*outc)();
{
register int nchars;
register int tpc;
if (ptime >= 0) {
if (ospeed >= 0 && ospeed <= (sizeof(times)/ sizeof(int))) {
tpc = times[ospeed];
ptime += (tpc / 2);
nchars = ptime / tpc;
for ( ; nchars > 0; --nchars) {
(*outc)(PC);
}
}
}
}
SHAR_EOF
cat << \SHAR_EOF > termlib/ttest.c
/************************************************************************
* *
* Copyright (c) 1982, Fred Fish *
* All Rights Reserved *
* *
* This software and/or documentation is released for public *
* distribution for personal, non-commercial use only. *
* Limited rights to use, modify, and redistribute are hereby *
* granted for non-commercial purposes, provided that all *
* copyright notices remain intact and all changes are clearly *
* documented. The author makes no warranty of any kind with *
* respect to this product and explicitly disclaims any implied *
* warranties of merchantability or fitness for any particular *
* purpose. *
* *
************************************************************************
*/
/*
* TEST PROGRAM
*
* testtcp test termcap functions
*
* KEY WORDS
*
* test routines
* termcap test
*
* SYNOPSIS
*
* termcap [-efns] terminal [capability [capability ...]]
*
* -e => expand string capability given by -s
* -f => determine boolean capabilities for terminal
* -n => determine numeric capabilities for terminal
* -s => determine string capabilities for terminal
*
* terminal => terminal name as given in termcap file
* capability => a boolean, numeric, or string capability
*
* NOTE: All capabilities must be of same type, as
* given by [-fns].
*
* If terminal is only argument then entire entry is
* printed.
*
* DESCRIPTION
*
* Provides way to test termcap functions. Can find
* and print an entire termcap terminal entry, or various
* capabilities from the entry.
*
* AUTHOR
*
* Fred Fish
*
*/
#include <stdio.h>
#define TRUE 1
#define FALSE 0
#define NO_FILE -1 /* Returned if can't open file */
#define NO_ENTRY 0 /* Returned if can't find entry */
#define SUCCESS 1 /* Returned if entry found ok */
#define TRUNCATED 2 /* Returned if entry found but trunc */
#define BUFFER_SIZE 1024
int eflag = FALSE;
int fflag = FALSE;
int nflag = FALSE;
int sflag = FALSE;
int got_terminal = FALSE;
int got_capability = FALSE;
int ospeed = 15; /* fake lots of padding */
/*
* FUNCTION
*
* main termcap test entry point
*
* KEY WORDS
*
* main
*
* SYNOPSIS
*
* main(argc,argv)
* int argc;
* char *argv[];
*
* DESCRIPTION
*
* This is where the termcap test starts executing. All argument list
* switches are processed first, then all the specified
* capability identification strings are processed.
*
*/
/*
* PSEUDO CODE
*
* Begin main
* Process command line options.
* For each argument list field
* If field was not erased during option processing
* If terminal name field not yet processed then
* Process an assumed terminal name field.
* Set terminal name processed flag.
* Else
* Process a capability field.
* Set capability field processed flag.
* End if
* End if
* End for
* If no capabilities processed then
* Simply dump buffer.
* End if
* End main
*
*/
main(argc, argv)
int argc;
char *argv[];
{
char *argp;
int argnum;
char buffer[BUFFER_SIZE];
options(argc,argv);
for (argnum = 1; argnum < argc; argnum++) {
if ((argp = argv[argnum]) != NULL) {
if (!got_terminal) {
terminal(buffer,argp);
got_terminal = TRUE;
} else {
capability(argp);
got_capability = TRUE;
}
}
}
if (got_terminal && !got_capability) {
printf("size = %d\n%s",strlen(buffer),buffer);
}
}
/*
* FUNCTION
*
* options process command line options
*
* SYNOPSIS
*
* options(argc,argv)
* int argc;
* char *argv[];
*
* DESCRIPTION
*
* Scans argument list, processing each switch as it is
* found. The pointer to each switch string is then
* replaced with a NULL to effectively erase the switch
* argument.
*
*/
/*
* PSEUDO CODE
*
* Begin options
* For each argument in the argument list
* Get pointer to first char of argument.
* If the argument is a switch then
* Replace argument pointer with NULL.
* Look at next argument character.
* While there is another argument character
* Switch on the argument character
* Case "EXPAND":
* Set expand (e) flag.
* Break out of switch.
* Case "BOOLEAN":
* Set boolean (f) flag.
* Break out of switch.
* Case "NUMERIC":
* Set numeric flag.
* Break out of switch.
* Case "STRING":
* Set string flag.
* Break out of switch.
* Default:
* Abort with usage message.
* End switch
* End while
* End if
* End for
* End options
*
*/
options(argc, argv)
int argc;
char *argv[];
{
int i;
char c; /* 1st char of current command-line argument */
char *cp; /* current argument pointer */
for (i=1; i<argc; i++) {
cp = argv[i];
if (*cp == '-') {
argv[i] = NULL;
cp++;
while (c = *cp++) {
switch (c) {
case 'e':
eflag = TRUE;
break;
case 'f':
fflag = TRUE;
break;
case 'n':
nflag = TRUE;
break;
case 's':
sflag = TRUE;
break;
default:
usage();
}
}
}
}
}
/*
* FUNCTION
*
* usage give usage message and abort
*
* KEY WORDS
*
* usage
* help processing
* abort locations
*
* SYNOPSIS
*
* usage()
*
* DESCRIPTION
*
* Usage is typically called when a problem has been
* detected in the argument list.
* It prints a usage message and exits.
*
*/
/*
* PSEUDO CODE
*
* Begin usage
* Print usage message.
* Exit.
* End usage
*
*/
usage()
{
printf("Usage: termcap [-fns] terminal [capability [capability ... ]]\n");
exit();
}
terminal(buffer,name)
char *buffer;
char *name;
{
int status;
status = tgetent(buffer,name);
switch (status) {
case NO_FILE:
fprintf(stderr,"Can't find a termcap data base file.\n");
exit();
case NO_ENTRY:
fprintf(stderr,"Can't find entry \"%s\"\n",name);
exit();
case TRUNCATED:
fprintf(stderr,"Warning --- entry \"%s\" too long\n",name);
break;
case SUCCESS:
break;
default:
fprintf(stderr,"? tgetent returned illegal status %d\n",status);
exit();
}
}
capability(id)
char *id;
{
int value;
char buffer[256];
char *area;
char *ep, *tgoto();
if (fflag) {
value = tgetflag(id);
if (value) {
printf("%s TRUE\n",id);
} else {
printf("%s FALSE\n",id);
}
} else if (nflag) {
value = tgetnum(id);
printf("%s = %o octal %d decimal\n",id,value,value);
} else if (sflag) {
area = buffer;
tgetstr(id,&area);
if (eflag) {
ep = tgoto(buffer,75,23);
}
doprint(id,buffer);
if (eflag) {
doprint(id,ep);
ep = tgoto(buffer,1,2);
doprint(id,ep);
}
}
}
/*
* Use tputs to get a clearer picture of exactly what
* goes out to the terminal....
*/
princ(c)
int c;
{
if (c < 040)
printf("^%c",c |= 0100);
else
printf("%c",c);
}
doprint(id,cp)
char *id;
char *cp;
{
printf("%s = \"",id);
tputs(cp, 1, princ);
printf("\"\n");
}
SHAR_EOF
# End of shell archive
exit 0
-------
More information about the Comp.sources.misc
mailing list