Annotation of src/usr.bin/tput/tput.c, Revision 1.7
1.6 millert 1: /* $OpenBSD: tput.c,v 1.5 1997/06/24 02:40:15 dgregor Exp $ */
1.1 deraadt 2: /* $NetBSD: tput.c,v 1.8 1995/08/31 22:11:37 jtc Exp $ */
3:
4: /*-
5: * Copyright (c) 1980, 1988, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by the University of
19: * California, Berkeley and its contributors.
20: * 4. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: */
36:
37: #ifndef lint
38: static char copyright[] =
39: "@(#) Copyright (c) 1980, 1988, 1993\n\
40: The Regents of the University of California. All rights reserved.\n";
41: #endif /* not lint */
42:
43: #ifndef lint
44: #if 0
45: static char sccsid[] = "@(#)tput.c 8.3 (Berkeley) 4/28/95";
46: #endif
1.6 millert 47: static char rcsid[] = "$OpenBSD: tput.c,v 1.5 1997/06/24 02:40:15 dgregor Exp $";
1.1 deraadt 48: #endif /* not lint */
49:
50: #include <termios.h>
51:
52: #include <err.h>
53: #include <curses.h>
54: #include <stdio.h>
55: #include <stdlib.h>
56: #include <unistd.h>
1.5 dgregor 57: #include <string.h>
1.1 deraadt 58:
59: static void prlongname __P((char *));
60: static void setospeed __P((void));
1.7 ! millert 61: static void outc __P((int));
1.1 deraadt 62: static void usage __P((void));
63: static char **process __P((char *, char *, char **));
64:
65: int
66: main(argc, argv)
67: int argc;
68: char **argv;
69: {
1.7 ! millert 70: extern char *optarg;
! 71: extern int optind;
! 72: int ch, exitval, n;
! 73: char *argv0, *cptr, *p, *term, buf[1024], tbuf[1024];
1.1 deraadt 74:
75: term = NULL;
1.7 ! millert 76: while ((ch = getopt(argc, argv, "T:")) != -1)
1.1 deraadt 77: switch(ch) {
78: case 'T':
79: term = optarg;
80: break;
81: case '?':
82: default:
83: usage();
84: }
1.7 ! millert 85: if ((argv0 = (char *)strrchr(argv[0], '/')) != NULL)
! 86: argv0++;
! 87: else
! 88: argv0 = argv[0];
1.1 deraadt 89: argc -= optind;
90: argv += optind;
91:
1.4 gene 92:
1.1 deraadt 93: if (!term && !(term = getenv("TERM")))
94: errx(2, "no terminal type specified and no TERM environmental variable.");
1.7 ! millert 95: if (tgetent(tbuf, term) != 1)
! 96: err(2, "tgetent failure");
1.1 deraadt 97: setospeed();
1.7 ! millert 98: if (strcmp(argv0, "clear") == 0) {
1.4 gene 99: *argv = "clear";
100: *(argv+1) = NULL;
101: }
1.1 deraadt 102: for (exitval = 0; (p = *argv) != NULL; ++argv) {
103: switch (*p) {
1.7 ! millert 104: case 'c':
! 105: if (!strcmp(p, "clear"))
! 106: p = "cl";
! 107: break;
1.1 deraadt 108: case 'i':
109: if (!strcmp(p, "init"))
1.7 ! millert 110: p = "is";
1.1 deraadt 111: break;
112: case 'l':
113: if (!strcmp(p, "longname")) {
1.7 ! millert 114: prlongname(tbuf);
1.1 deraadt 115: continue;
116: }
117: break;
118: case 'r':
119: if (!strcmp(p, "reset"))
1.7 ! millert 120: p = "rs";
1.1 deraadt 121: break;
122: }
1.7 ! millert 123: cptr = buf;
! 124: if (tgetstr(p, &cptr))
! 125: argv = process(p, buf, argv);
! 126: else if ((n = tgetnum(p)) != -1)
1.1 deraadt 127: (void)printf("%d\n", n);
128: else
1.7 ! millert 129: exitval = !tgetflag(p);
1.1 deraadt 130:
131: if (argv == NULL)
132: break;
133: }
134: exit(argv ? exitval : 2);
135: }
136:
137: static void
138: prlongname(buf)
139: char *buf;
140: {
141: int savech;
142: char *p, *savep;
143:
144: for (p = buf; *p && *p != ':'; ++p)
145: continue;
146: savech = *(savep = p);
147: for (*p = '\0'; p >= buf && *p != '|'; --p)
148: continue;
149: (void)printf("%s\n", p + 1);
150: *savep = savech;
151: }
152:
153: static char **
154: process(cap, str, argv)
155: char *cap, *str, **argv;
156: {
157: static char errfew[] =
158: "not enough arguments (%d) for capability `%s'";
159: static char errmany[] =
160: "too many arguments (%d) for capability `%s'";
161: static char erresc[] =
162: "unknown %% escape `%c' for capability `%s'";
163: char *cp;
164: int arg_need, arg_rows, arg_cols;
165:
166: /* Count how many values we need for this capability. */
167: for (cp = str, arg_need = 0; *cp != '\0'; cp++)
168: if (*cp == '%')
169: switch (*++cp) {
170: case 'd':
171: case '2':
172: case '3':
173: case '.':
174: case '+':
175: arg_need++;
176: break;
177: case '%':
178: case '>':
179: case 'i':
180: case 'r':
181: case 'n':
182: case 'B':
183: case 'D':
184: break;
185: default:
186: /*
1.7 ! millert 187: * hpux has lot's of them, but we complain
1.1 deraadt 188: */
189: errx(2, erresc, *cp, cap);
190: }
191:
192: /* And print them. */
193: switch (arg_need) {
194: case 0:
1.7 ! millert 195: (void)tputs(str, 1, outc);
1.1 deraadt 196: break;
197: case 1:
198: arg_cols = 0;
199:
200: if (*++argv == NULL || *argv[0] == '\0')
201: errx(2, errfew, 1, cap);
202: arg_rows = atoi(*argv);
203:
1.7 ! millert 204: (void)tputs(tgoto(str, arg_cols, arg_rows), 1, outc);
1.1 deraadt 205: break;
206: case 2:
207: if (*++argv == NULL || *argv[0] == '\0')
208: errx(2, errfew, 2, cap);
209: arg_rows = atoi(*argv);
210:
211: if (*++argv == NULL || *argv[0] == '\0')
212: errx(2, errfew, 2, cap);
213: arg_cols = atoi(*argv);
214:
1.7 ! millert 215: (void) tputs(tgoto(str, arg_cols, arg_rows), arg_rows, outc);
1.1 deraadt 216: break;
217:
218: default:
219: errx(2, errmany, arg_need, cap);
220: }
221: return (argv);
222: }
223:
224: static void
225: setospeed()
226: {
227: #undef ospeed
228: extern short ospeed;
229: struct termios t;
230:
231: if (tcgetattr(STDOUT_FILENO, &t) != -1)
232: ospeed = 0;
233: else
234: ospeed = cfgetospeed(&t);
235: }
236:
237: static void
1.7 ! millert 238: outc(c)
! 239: int c;
! 240: {
! 241: (void)putchar(c);
! 242: }
! 243:
! 244: static void
1.1 deraadt 245: usage()
246: {
1.7 ! millert 247: (void)fprintf(stderr, "usage: tput [-T term] attribute ...\n");
1.1 deraadt 248: exit(1);
249: }