|
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); } }