|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T t
Length: 5648 (0x1610)
Types: TextFile
Names: »tput.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/euug-87hel/sec1/tput/tput.c«
#ifndef LINT
static char rcsid[] = "$Header: tput.c,v 1.6 86/09/19 17:01:00 badri Exp $" ;
#endif LINT
/*
* Copyright (C) $Date: 86/09/19 17:01:00 $
* by $Author: badri $
* University of Rochester,
* Department of Electrical Engineering.
*
* CoNtEnTs This file contains a program to emulate the system V
* CoNtEnTs version of tput.
*
* $Locker: $
* $Source: /u/users/badri/usr/src/local/tput/RCS/tput.c,v $
* $Revision: 1.6 $
*
* History of this release:
* $Log: tput.c,v $
* Revision 1.6 86/09/19 17:01:00 badri
* Updated to incorporate -e flag etc.
*
* Revision 1.5 86/09/18 20:58:09 badri
* Rewrote match, which had a bug in it!
*
* Revision 1.4 86/09/18 15:43:34 badri
* Updated to incorporate all flags of the old SV tput plus cursor movement
* plus -n flag to affect number of lines (if permitted.)
*
* Revision 1.3 86/09/18 15:34:51 badri
* This is an interim version to make tput more compatible with SV.
* Mods suggested by mark@cbosgd (Mark Horton)
*
* Revision 1.2 86/08/22 13:39:27 badri
* 1. Corrected a bug that would cause %d to fail after %%.
* 2. Included XTABS handling.
* 3. General cleanup of code.
* 1. Corrected a bug that would cause %d to fail after %%.
* 2. Included XTABS handling.
* 3. General cleanup of code.
*
* Revision 1.1 86/08/21 19:23:33 badri
* Initial revision
*
*/
#include "tput.h"
main(argc,argv)
int argc;
char *argv[];
{
char bp[LARGEBUF], *getenv(), *tgetstr(), *tgoto(),
buf[SMALLBUF], *id, *area, *ptr;
int outc();
struct sgttyb ttyprm;
unsigned short ttyflg, arg, start, pos, end;
long affcnt, val;
if (argc < 2) quit(BADUSE,"fubar");
arg = 1;
affcnt = 1;
val = -1; /* This is used for examining if type of
* terminal is explicitly specified.
*/
while (argv[arg][0] == '-')
{
switch (argv[arg][1])
{
case 'T': /* Terminal type */
if (argv[arg][2] == '\0' || argc < 3)
quit(BADUSE,"fubar");
if (tgetent(bp,&argv[arg][2]) < 1)
quit(BADTERM,&argv[arg][2]);
val = 0;
break;
case 'e': /* Suppress printing of error message */
errsup = 1;
break;
case 'n': /* No. of affected lines */
affcnt = atoi(&argv[arg][2]);
break;
default:
quit(BADUSE,"fubar");
}
arg++;
}
if (val < 0)
if (tgetent(bp,getenv("TERM")) < 1)
quit(BADTERM,"in environment variable TERM");
/* Begin a binary search for capability in table */
for (start = 0, end = TABLESIZE - 1, pos = (end - start) >> 1;
end - start > 1; pos = start + ((end - start) >> 1))
{
switch (match(argv[arg],table[pos].key))
{
case -1: /* Lexicographically less than pos */
end = pos;
continue;
case 0: /* A hit! */
id = table[pos].value;
goto WORK;
case 1: /* Lexicographically greater than pos. */
start = pos;
continue;
}
}
/* Examine the current start and end positions of table for match */
if (!match(argv[arg],table[start].key)) id = table[start].value;
else if (!match(argv[arg],table[end].key)) id = table[end].value;
else quit(BADCAP,argv[arg]); /* Could not find capability in table */
WORK:
/* At this point we know that the capability exists in our
* table, but we do not know if it is of type boolean, string
* or has a numeric value (or does not exist.)
*/
if ((val = tgetnum(id)) != -1)
{
/* It has a numeric value. Print it and quit. */
fprintf(stdout, "%d\n",val);
quit(SUCCESS,"tput");
}
/* It is of type string (or boolean) */
area = buf;
if (!tgetstr(id,&area))
{
/* Boolean */
if (tgetflag(id)) quit(SUCCESS,"tput");
else quit(FAILURE,"tput");
}
/*
* It is of type string.
* Examine if cursor movement specified. This is done
* by looking for % followed by any but %. Since %%
* is a single %, we have to make sure that %% followed
* by any but % is not interpreted as a format.
* If cursor movement is specified then tgoto needs
* to be invoked. Else put as is.
*/
ptr = buf;
while (*ptr != '\0')
{
if (*(ptr++) != '%') continue;
if (*ptr != '\0' && *(ptr++) != '%')
{
/* This string is a cm string. Increment arg to
* position it over the numeric argument (if specified!)
*/
if (argc - ++arg < 2) quit(BADUSE,"fubar");
if (*(ptr=tgoto(buf,atoi(argv[arg+1]),atoi(argv[arg])))
== 'O' && *(ptr+1) == 'O' &&
*(ptr+2) == 'P' && *(ptr+3) == 'S')
quit(BADUSE,"fubar");
/* Turn off XTABS, but save old flags first. */
if (gtty(fileno(stdout),&ttyprm) < 0)
quit(SYSTEM,"fubar");
ttyflg = ttyprm.sg_flags;
ttyprm.sg_flags &= ~XTABS;
if (stty(fileno(stdout),&ttyprm) < 0)
quit(SYSTEM,"fubar");
tputs(ptr,affcnt,outc);
/* Restore old flags. */
ttyprm.sg_flags = ttyflg;
if (stty(fileno(stdout),&ttyprm) < 0)
quit(SYSTEM,"fubar");
quit(SUCCESS,"tput");
}
quit(BADUSE,"fubar");
}
tputs(buf,affcnt,outc);
quit(SUCCESS,"tput");
}
outc(c)
char c;
{
if (write(fileno(stdout),&c,sizeof(char)) < 0)
quit(SYSTEM,"fubar");
return(SUCCESS);
}
match(s1,s2)
char *s1, *s2;
{
while (*s1 == *s2)
{
if (*s1 == '\0') return(0);
s1++, s2++;
}
return(*s1 > *s2 ? 1:-1);
}
quit(i,s)
int i;
char *s;
{
if (errsup)
{
if (i < SYSTEM) exit(i);
else exit(errno);
}
switch(i)
{
case SUCCESS:
case FAILURE:
exit(i);
case BADUSE:
fprintf(stderr,
"Usage: tput [ -Ttype ] [ -e ] [ -nlines ] capname [ x y ]\n");
exit(i);
case BADTERM:
fprintf(stderr, "Bad terminal type: %s\n",s);
exit(i);
case BADCAP:
fprintf(stderr, "Bad capability: %s\n",s);
exit(i);
case SYSTEM:
fprintf(stderr, "Terminal I/O error - examine exit status\n");
exit(errno);
}
}