home *** CD-ROM | disk | FTP | other *** search
- #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);
- }
- }
-