Annotation of src/usr.bin/tput/tput.c, Revision 1.6
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>
1.6 ! millert 54: #include <term.h>
1.1 deraadt 55: #include <stdio.h>
56: #include <stdlib.h>
57: #include <unistd.h>
1.5 dgregor 58: #include <string.h>
1.1 deraadt 59:
60: static void prlongname __P((char *));
61: static void setospeed __P((void));
62: static void usage __P((void));
63: static char **process __P((char *, char *, char **));
64:
1.6 ! millert 65: extern char *__progname;
! 66:
1.1 deraadt 67: int
68: main(argc, argv)
69: int argc;
70: char **argv;
71: {
1.6 ! millert 72: int ch, exitval, n, Sflag = 0;
! 73: size_t len;
! 74: char *p, *term, *str;
1.1 deraadt 75:
76: term = NULL;
1.6 ! millert 77: while ((ch = getopt(argc, argv, "ST:")) != -1)
1.1 deraadt 78: switch(ch) {
79: case 'T':
80: term = optarg;
81: break;
1.6 ! millert 82: case 'S':
! 83: Sflag = 1;
! 84: break;
1.1 deraadt 85: case '?':
86: default:
87: usage();
88: }
89: argc -= optind;
90: argv += optind;
91:
1.6 ! millert 92: if (Sflag && argc > 0)
! 93: usage();
1.4 gene 94:
1.1 deraadt 95: if (!term && !(term = getenv("TERM")))
96: errx(2, "no terminal type specified and no TERM environmental variable.");
1.6 ! millert 97: if (setupterm(term, STDOUT_FILENO, NULL) == ERR)
! 98: err(2, "setupterm failure");
1.1 deraadt 99: setospeed();
1.6 ! millert 100: if (strcmp(__progname, "clear") == 0) {
! 101: if (Sflag)
! 102: usage();
1.4 gene 103: *argv = "clear";
104: *(argv+1) = NULL;
105: }
1.6 ! millert 106: if (Sflag) {
! 107: char **av;
! 108:
! 109: /* Build new argv based on stdin */
! 110: argc = n = 0;
! 111: av = NULL;
! 112: while ((str = fgetln(stdin, &len)) != NULL) {
! 113: if (str[len-1] != '\n')
! 114: errx(1, "premature EOF");
! 115: str[len-1] = '\0';
! 116: /* grow av as needed */
! 117: if (argc + 1 >= n) {
! 118: n += 64;
! 119: av = (char **)realloc(av, sizeof(char *) * n);
! 120: if (av == NULL)
! 121: errx(1, "out of memory");
! 122: av = &av[argc];
! 123: }
! 124: while ((p = strsep(&str, " \t")) != NULL)
! 125: if ((av[argc++] = strdup(p)) == NULL)
! 126: errx(1, "out of memory");
! 127: }
! 128: if (argc > 0) {
! 129: av[argc] = NULL;
! 130: argv = av;
! 131: }
! 132: }
1.1 deraadt 133: for (exitval = 0; (p = *argv) != NULL; ++argv) {
134: switch (*p) {
135: case 'i':
136: if (!strcmp(p, "init"))
1.6 ! millert 137: p = "is2"; /* XXX - is1 as well? */
1.1 deraadt 138: break;
139: case 'l':
140: if (!strcmp(p, "longname")) {
1.6 ! millert 141: prlongname(CUR term_names);
1.1 deraadt 142: continue;
143: }
144: break;
145: case 'r':
146: if (!strcmp(p, "reset"))
1.6 ! millert 147: p = "rs2"; /* XXX - rs1 as well? */
1.1 deraadt 148: break;
149: }
1.6 ! millert 150: /* XXX - check termcap names too */
! 151: if ((str = tigetstr(p)) != NULL && str != (char *)-1)
! 152: argv = process(p, str, argv);
! 153: else if ((n = tigetnum(p)) != -1 && n != -2)
1.1 deraadt 154: (void)printf("%d\n", n);
155: else
1.6 ! millert 156: exitval = (tigetflag(p) == -1);
1.1 deraadt 157:
158: if (argv == NULL)
159: break;
160: }
161: exit(argv ? exitval : 2);
162: }
163:
164: static void
165: prlongname(buf)
166: char *buf;
167: {
168: int savech;
169: char *p, *savep;
170:
171: for (p = buf; *p && *p != ':'; ++p)
172: continue;
173: savech = *(savep = p);
174: for (*p = '\0'; p >= buf && *p != '|'; --p)
175: continue;
176: (void)printf("%s\n", p + 1);
177: *savep = savech;
178: }
179:
180: static char **
181: process(cap, str, argv)
182: char *cap, *str, **argv;
183: {
184: static char errfew[] =
185: "not enough arguments (%d) for capability `%s'";
186: static char errmany[] =
187: "too many arguments (%d) for capability `%s'";
188: static char erresc[] =
189: "unknown %% escape `%c' for capability `%s'";
190: char *cp;
191: int arg_need, arg_rows, arg_cols;
192:
193: /* Count how many values we need for this capability. */
194: for (cp = str, arg_need = 0; *cp != '\0'; cp++)
195: if (*cp == '%')
196: switch (*++cp) {
197: case 'd':
198: case '2':
199: case '3':
200: case '.':
201: case '+':
202: arg_need++;
203: break;
204: case '%':
205: case '>':
206: case 'i':
207: case 'r':
208: case 'n':
209: case 'B':
210: case 'D':
211: break;
212: default:
213: /*
1.6 ! millert 214: * HP-UX has lots of them, but we complain
1.1 deraadt 215: */
216: errx(2, erresc, *cp, cap);
217: }
218:
219: /* And print them. */
220: switch (arg_need) {
221: case 0:
1.6 ! millert 222: (void)putp(str);
1.1 deraadt 223: break;
224: case 1:
225: arg_cols = 0;
226:
227: if (*++argv == NULL || *argv[0] == '\0')
228: errx(2, errfew, 1, cap);
229: arg_rows = atoi(*argv);
230:
1.6 ! millert 231: (void)putp(tparm(str, arg_cols, arg_rows));
1.1 deraadt 232: break;
233: case 2:
234: if (*++argv == NULL || *argv[0] == '\0')
235: errx(2, errfew, 2, cap);
236: arg_rows = atoi(*argv);
237:
238: if (*++argv == NULL || *argv[0] == '\0')
239: errx(2, errfew, 2, cap);
240: arg_cols = atoi(*argv);
241:
1.6 ! millert 242: (void) tputs(tparm(str, arg_cols, arg_rows), arg_rows, putchar);
1.1 deraadt 243: break;
244:
245: default:
246: errx(2, errmany, arg_need, cap);
247: }
248: return (argv);
249: }
250:
251: static void
252: setospeed()
253: {
254: #undef ospeed
255: extern short ospeed;
256: struct termios t;
257:
258: if (tcgetattr(STDOUT_FILENO, &t) != -1)
259: ospeed = 0;
260: else
261: ospeed = cfgetospeed(&t);
262: }
263:
264: static void
265: usage()
266: {
1.6 ! millert 267: (void)fprintf(stderr,
! 268: "usage: %s [-T term] attribute [attribute-args] ...\n"
! 269: " %s [-T term] -S\n", __progname, __progname);
1.1 deraadt 270: exit(1);
271: }