Annotation of src/usr.bin/tput/tput.c, Revision 1.4
1.4 ! gene 1: /* $OpenBSD: tput.c,v 1.3 1997/01/15 23:43:23 millert 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.4 ! gene 47: static char rcsid[] = "$OpenBSD: tput.c,v 1.3 1997/01/15 23:43:23 millert 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>
57:
58: static void prlongname __P((char *));
59: static void setospeed __P((void));
60: static void outc __P((int));
61: static void usage __P((void));
62: static char **process __P((char *, char *, char **));
63:
64: int
65: main(argc, argv)
66: int argc;
67: char **argv;
68: {
69: extern char *optarg;
70: extern int optind;
71: int ch, exitval, n;
1.4 ! gene 72: char *argv0, *cptr, *p, *term, buf[1024], tbuf[1024];
1.1 deraadt 73:
74: term = NULL;
1.3 millert 75: while ((ch = getopt(argc, argv, "T:")) != -1)
1.1 deraadt 76: switch(ch) {
77: case 'T':
78: term = optarg;
79: break;
80: case '?':
81: default:
82: usage();
83: }
1.4 ! gene 84: if ((argv0 = (char *)strrchr(argv[0], '/')) != NULL)
! 85: argv0++;
! 86: else
! 87: argv0 = argv[0];
1.1 deraadt 88: argc -= optind;
89: argv += optind;
90:
1.4 ! gene 91:
1.1 deraadt 92: if (!term && !(term = getenv("TERM")))
93: errx(2, "no terminal type specified and no TERM environmental variable.");
94: if (tgetent(tbuf, term) != 1)
95: err(2, "tgetent failure");
96: setospeed();
1.4 ! gene 97: if (strcmp(argv0, "clear") == 0) {
! 98: *argv = "clear";
! 99: *(argv+1) = NULL;
! 100: }
1.1 deraadt 101: for (exitval = 0; (p = *argv) != NULL; ++argv) {
102: switch (*p) {
103: case 'c':
104: if (!strcmp(p, "clear"))
105: p = "cl";
106: break;
107: case 'i':
108: if (!strcmp(p, "init"))
109: p = "is";
110: break;
111: case 'l':
112: if (!strcmp(p, "longname")) {
113: prlongname(tbuf);
114: continue;
115: }
116: break;
117: case 'r':
118: if (!strcmp(p, "reset"))
119: p = "rs";
120: break;
121: }
122: cptr = buf;
123: if (tgetstr(p, &cptr))
124: argv = process(p, buf, argv);
125: else if ((n = tgetnum(p)) != -1)
126: (void)printf("%d\n", n);
127: else
128: exitval = !tgetflag(p);
129:
130: if (argv == NULL)
131: break;
132: }
133: exit(argv ? exitval : 2);
134: }
135:
136: static void
137: prlongname(buf)
138: char *buf;
139: {
140: int savech;
141: char *p, *savep;
142:
143: for (p = buf; *p && *p != ':'; ++p)
144: continue;
145: savech = *(savep = p);
146: for (*p = '\0'; p >= buf && *p != '|'; --p)
147: continue;
148: (void)printf("%s\n", p + 1);
149: *savep = savech;
150: }
151:
152: static char **
153: process(cap, str, argv)
154: char *cap, *str, **argv;
155: {
156: static char errfew[] =
157: "not enough arguments (%d) for capability `%s'";
158: static char errmany[] =
159: "too many arguments (%d) for capability `%s'";
160: static char erresc[] =
161: "unknown %% escape `%c' for capability `%s'";
162: char *cp;
163: int arg_need, arg_rows, arg_cols;
164:
165: /* Count how many values we need for this capability. */
166: for (cp = str, arg_need = 0; *cp != '\0'; cp++)
167: if (*cp == '%')
168: switch (*++cp) {
169: case 'd':
170: case '2':
171: case '3':
172: case '.':
173: case '+':
174: arg_need++;
175: break;
176: case '%':
177: case '>':
178: case 'i':
179: case 'r':
180: case 'n':
181: case 'B':
182: case 'D':
183: break;
184: default:
185: /*
186: * hpux has lot's of them, but we complain
187: */
188: errx(2, erresc, *cp, cap);
189: }
190:
191: /* And print them. */
192: switch (arg_need) {
193: case 0:
194: (void)tputs(str, 1, outc);
195: break;
196: case 1:
197: arg_cols = 0;
198:
199: if (*++argv == NULL || *argv[0] == '\0')
200: errx(2, errfew, 1, cap);
201: arg_rows = atoi(*argv);
202:
203: (void)tputs(tgoto(str, arg_cols, arg_rows), 1, outc);
204: break;
205: case 2:
206: if (*++argv == NULL || *argv[0] == '\0')
207: errx(2, errfew, 2, cap);
208: arg_rows = atoi(*argv);
209:
210: if (*++argv == NULL || *argv[0] == '\0')
211: errx(2, errfew, 2, cap);
212: arg_cols = atoi(*argv);
213:
214: (void) tputs(tgoto(str, arg_cols, arg_rows), arg_rows, outc);
215: break;
216:
217: default:
218: errx(2, errmany, arg_need, cap);
219: }
220: return (argv);
221: }
222:
223: static void
224: setospeed()
225: {
226: #undef ospeed
227: extern short ospeed;
228: struct termios t;
229:
230: if (tcgetattr(STDOUT_FILENO, &t) != -1)
231: ospeed = 0;
232: else
233: ospeed = cfgetospeed(&t);
234: }
235:
236: static void
237: outc(c)
238: int c;
239: {
240: (void)putchar(c);
241: }
242:
243: static void
244: usage()
245: {
246: (void)fprintf(stderr, "usage: tput [-T term] attribute ...\n");
247: exit(1);
248: }