xref: /original-bsd/usr.bin/tput/tput.c (revision 00695d63)
1 /*-
2  * Copyright (c) 1980, 1988, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char copyright[] =
10 "@(#) Copyright (c) 1980, 1988, 1993\n\
11 	The Regents of the University of California.  All rights reserved.\n";
12 #endif /* not lint */
13 
14 #ifndef lint
15 static char sccsid[] = "@(#)tput.c	8.3 (Berkeley) 04/28/95";
16 #endif /* not lint */
17 
18 #include <sys/termios.h>
19 
20 #include <err.h>
21 #include <curses.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 
26 static void   prlongname __P((char *));
27 static void   setospeed __P((void));
28 static void   outc __P((int));
29 static void   usage __P((void));
30 static char **process __P((char *, char *, char **));
31 
32 int
33 main(argc, argv)
34 	int argc;
35 	char **argv;
36 {
37 	extern char *optarg;
38 	extern int optind;
39 	int ch, exitval, n;
40 	char *cptr, *p, *term, buf[1024], tbuf[1024];
41 
42 	term = NULL;
43 	while ((ch = getopt(argc, argv, "T:")) != EOF)
44 		switch(ch) {
45 		case 'T':
46 			term = optarg;
47 			break;
48 		case '?':
49 		default:
50 			usage();
51 		}
52 	argc -= optind;
53 	argv += optind;
54 
55 	if (!term && !(term = getenv("TERM")))
56 errx(2, "no terminal type specified and no TERM environmental variable.");
57 	if (tgetent(tbuf, term) != 1)
58 		err(2, "tgetent failure");
59 	setospeed();
60 	for (exitval = 0; (p = *argv) != NULL; ++argv) {
61 		switch (*p) {
62 		case 'c':
63 			if (!strcmp(p, "clear"))
64 				p = "cl";
65 			break;
66 		case 'i':
67 			if (!strcmp(p, "init"))
68 				p = "is";
69 			break;
70 		case 'l':
71 			if (!strcmp(p, "longname"))
72 				prlongname(tbuf);
73 			continue;
74 		case 'r':
75 			if (!strcmp(p, "reset"))
76 				p = "rs";
77 			break;
78 		}
79 		cptr = buf;
80 		if (tgetstr(p, &cptr))
81 			argv = process(p, buf, argv);
82 		else if ((n = tgetnum(p)) != -1)
83 			(void)printf("%d\n", n);
84 		else
85 			exitval = !tgetflag(p);
86 	}
87 	exit(exitval);
88 }
89 
90 static void
91 prlongname(buf)
92 	char *buf;
93 {
94 	int savech;
95 	char *p, *savep;
96 
97 	for (p = buf; *p && *p != ':'; ++p);
98 	savech = *(savep = p);
99 	for (*p = '\0'; p >= buf && *p != '|'; --p);
100 	(void)printf("%s\n", p + 1);
101 	*savep = savech;
102 }
103 
104 static char **
105 process(cap, str, argv)
106 	char *cap, *str, **argv;
107 {
108 	static char errfew[] =
109 	    "not enough arguments (%d) for capability `%s'";
110 	static char errmany[] =
111 	    "too many arguments (%d) for capability `%s'";
112 	static char erresc[] =
113 	    "unknown %% escape `%c' for capability `%s'";
114 	char *cp;
115 	int arg_need, arg_rows, arg_cols;
116 
117 	/* Count how many values we need for this capability. */
118 	for (cp = str, arg_need = 0; *cp != '\0'; cp++)
119 		if (*cp == '%')
120 			    switch (*++cp) {
121 			    case 'd':
122 			    case '2':
123 			    case '3':
124 			    case '.':
125 			    case '+':
126 				    arg_need++;
127 				    break;
128 			    case '%':
129 			    case '>':
130 			    case 'i':
131 			    case 'r':
132 			    case 'n':
133 			    case 'B':
134 			    case 'D':
135 				    break;
136 			    default:
137 				/*
138 				 * hpux has lot's of them, but we complain
139 				 */
140 				 errx(2, erresc, *cp, cap);
141 			    }
142 
143 	/* And print them. */
144 	switch (arg_need) {
145 	case 0:
146 		(void)tputs(str, 1, outc);
147 		break;
148 	case 1:
149 		arg_cols = 0;
150 
151 		if (*++argv == NULL || *argv[0] == '\0')
152 			errx(2, errfew, 1, cap);
153 		arg_rows = atoi(*argv);
154 
155 		(void)tputs(tgoto(str, arg_cols, arg_rows), 1, outc);
156 		break;
157 	case 2:
158 		if (*++argv == NULL || *argv[0] == '\0')
159 			errx(2, errfew, 2, cap);
160 		arg_rows = atoi(*argv);
161 
162 		if (*++argv == NULL || *argv[0] == '\0')
163 			errx(2, errfew, 2, cap);
164 		arg_cols = atoi(*argv);
165 
166 		(void) tputs(tgoto(str, arg_cols, arg_rows), arg_rows, outc);
167 		break;
168 
169 	default:
170 		errx(2, errmany, arg_need, cap);
171 	}
172 	return (argv);
173 }
174 
175 static void
176 setospeed()
177 {
178 #undef ospeed
179 	extern short ospeed;
180 	struct termios t;
181 
182 	if (tcgetattr(STDOUT_FILENO, &t) != -1)
183 		ospeed = 0;
184 	else
185 		ospeed = cfgetospeed(&t);
186 }
187 
188 static void
189 outc(c)
190 	int c;
191 {
192 	(void)putchar(c);
193 }
194 
195 static void
196 usage()
197 {
198 	(void)fprintf(stderr, "usage: tput [-T term] attribute ...\n");
199 	exit(1);
200 }
201