xref: /freebsd/contrib/ncurses/progs/tput.c (revision 4cf49a43559ed9fdad601bdcccd2c55963008675)
1 /****************************************************************************
2  * Copyright (c) 1998 Free Software Foundation, Inc.                        *
3  *                                                                          *
4  * Permission is hereby granted, free of charge, to any person obtaining a  *
5  * copy of this software and associated documentation files (the            *
6  * "Software"), to deal in the Software without restriction, including      *
7  * without limitation the rights to use, copy, modify, merge, publish,      *
8  * distribute, distribute with modifications, sublicense, and/or sell       *
9  * copies of the Software, and to permit persons to whom the Software is    *
10  * furnished to do so, subject to the following conditions:                 *
11  *                                                                          *
12  * The above copyright notice and this permission notice shall be included  *
13  * in all copies or substantial portions of the Software.                   *
14  *                                                                          *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
18  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
21  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
22  *                                                                          *
23  * Except as contained in this notice, the name(s) of the above copyright   *
24  * holders shall not be used in advertising or otherwise to promote the     *
25  * sale, use or other dealings in this Software without prior written       *
26  * authorization.                                                           *
27  ****************************************************************************/
28 
29 /****************************************************************************
30  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
31  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
32  ****************************************************************************/
33 
34 
35 /*
36  * tput.c -- shellscript access to terminal capabilities
37  *
38  * by Eric S. Raymond <esr@snark.thyrsus.com>, portions based on code from
39  * Ross Ridge's mytinfo package.
40  */
41 
42 #include <progs.priv.h>
43 #ifndef	PURE_TERMINFO
44 #include <termsort.c>
45 #endif
46 
47 MODULE_ID("$Id: tput.c,v 1.14 1999/07/31 21:18:29 Goran.Uddeborg Exp $")
48 
49 #define PUTS(s)		fputs(s, stdout)
50 #define PUTCHAR(c)	putchar(c)
51 #define FLUSH		fflush(stdout)
52 
53 static char *prg_name;
54 
55 static void quit(int status, const char *fmt, ...)
56 {
57 va_list argp;
58 
59 	va_start(argp,fmt);
60 	vfprintf (stderr, fmt, argp);
61 	fprintf(stderr, "\n");
62 	va_end(argp);
63 	exit(status);
64 }
65 
66 static void usage(void)
67 {
68 	fprintf(stderr, "usage: %s [-S] [-T term] capname\n", prg_name);
69 	exit(EXIT_FAILURE);
70 }
71 
72 static int tput(int argc, char *argv[])
73 {
74 char *name;
75 char *s;
76 int i, j, c;
77 int reset, status;
78 FILE *f;
79 
80 	reset = 0;
81 	name = argv[0];
82 	if (strcmp(name, "reset") == 0) {
83 		reset = 1;
84 	}
85 	if (reset || strcmp(name, "init") == 0) {
86 		if (init_prog != NULL) {
87 			system(init_prog);
88 		}
89 		FLUSH;
90 
91 		if (reset && reset_1string != NULL) {
92 			PUTS(reset_1string);
93 		} else if (init_1string != NULL) {
94 			PUTS(init_1string);
95 		}
96 		FLUSH;
97 
98 		if (reset && reset_2string != NULL) {
99 			PUTS(reset_2string);
100 		} else if (init_2string != NULL) {
101 			PUTS(init_2string);
102 		}
103 		FLUSH;
104 
105 		if (set_lr_margin != NULL) {
106 			PUTS(tparm(set_lr_margin, 0, columns - 1));
107 		} else if (set_left_margin_parm != NULL
108 			   && set_right_margin_parm != NULL) {
109 			PUTS(tparm(set_left_margin_parm, 0));
110 			PUTS(tparm(set_right_margin_parm, columns - 1));
111 		} else if (clear_margins != NULL && set_left_margin != NULL
112 			   && set_right_margin != NULL) {
113 			PUTS(clear_margins);
114 			if (carriage_return != NULL) {
115 				PUTS(carriage_return);
116 			} else {
117 				PUTCHAR('\r');
118 			}
119 			PUTS(set_left_margin);
120 			if (parm_right_cursor) {
121 				PUTS(tparm(parm_right_cursor, columns - 1));
122 			} else {
123 				for(i = 0; i < columns - 1; i++) {
124 					PUTCHAR(' ');
125 				}
126 			}
127 			PUTS(set_right_margin);
128 			if (carriage_return != NULL) {
129 				PUTS(carriage_return);
130 			} else {
131 				PUTCHAR('\r');
132 			}
133 		}
134 		FLUSH;
135 
136 		if (init_tabs != 8) {
137 			if (clear_all_tabs != NULL && set_tab != NULL) {
138 				for(i = 0; i < columns - 1; i += 8) {
139 					if (parm_right_cursor) {
140 						PUTS(tparm(parm_right_cursor, 8));
141 					} else {
142 						for(j = 0; j < 8; j++)
143 							PUTCHAR(' ');
144 					}
145 					PUTS(set_tab);
146 				}
147 				FLUSH;
148 			}
149 		}
150 
151 		if (reset && reset_file != NULL) {
152 			f = fopen(reset_file, "r");
153 			if (f == NULL) {
154 				quit(errno, "Can't open reset_file: '%s'", reset_file);
155 			}
156 			while((c = fgetc(f)) != EOF) {
157 				PUTCHAR(c);
158 			}
159 			fclose(f);
160 		} else if (init_file != NULL) {
161 			f = fopen(init_file, "r");
162 			if (f == NULL) {
163 				quit(errno, "Can't open init_file: '%s'", init_file);
164 			}
165 			while((c = fgetc(f)) != EOF) {
166 				PUTCHAR(c);
167 			}
168 			fclose(f);
169 		}
170 		FLUSH;
171 
172 		if (reset && reset_3string != NULL) {
173 			PUTS(reset_3string);
174 		} else if (init_2string != NULL) {
175 			PUTS(init_2string);
176 		}
177 		FLUSH;
178 		return 0;
179 	}
180 
181 	if (strcmp(name, "longname") == 0) {
182 		PUTS(longname());
183 		return 0;
184 	}
185 
186 #ifndef	PURE_TERMINFO
187 	{
188 		const struct name_table_entry 	*np;
189 
190 		if ((np = _nc_find_entry(name, _nc_get_hash_table(1))) != 0)
191 			switch(np->nte_type)
192 			{
193 			case BOOLEAN:
194 				if (bool_from_termcap[np->nte_index])
195 					name = boolnames[np->nte_index];
196 				break;
197 
198 			case NUMBER:
199 				if (num_from_termcap[np->nte_index])
200 					name = numnames[np->nte_index];
201 				break;
202 
203 			case STRING:
204 				if (str_from_termcap[np->nte_index])
205 					name = strnames[np->nte_index];
206 				break;
207 			}
208 	}
209 #endif
210 
211 	if ((status = tigetflag(name)) != -1)
212 		return(status != 0);
213 	else if ((status = tigetnum(name)) != CANCELLED_NUMERIC) {
214 		(void) printf("%d\n", status);
215 		return(0);
216 	}
217 	else if ((s = tigetstr(name)) == CANCELLED_STRING)
218 		quit(4, "%s: unknown terminfo capability '%s'", prg_name, name);
219 	else if (s != (char *)NULL) {
220 		if (argc > 1) {
221 		int k;
222 
223 			/* Nasty hack time. The tparm function needs to see numeric
224 			 * parameters as numbers, not as pointers to their string
225 			 * representations
226 			 */
227 
228 			 for (k = 1; k < argc; k++)
229 			 	if (isdigit(argv[k][0])) {
230 			 		long val = atol(argv[k]);
231 			 		argv[k] = (char *)val;
232 				}
233 
234 				s = tparm(s,argv[1],argv[2],argv[3],argv[4],
235 					    argv[5],argv[6],argv[7],argv[8],
236 					    argv[9]);
237 		}
238 
239 		/* use putp() in order to perform padding */
240 		putp(s);
241 		return(0);
242 	}
243 	return(0);
244 }
245 
246 int main(int argc, char **argv)
247 {
248 char *s, *term;
249 int errret, cmdline = 1;
250 int c;
251 char	buf[BUFSIZ];
252 int errors = 0;
253 
254 	prg_name = argv[0];
255 	s = strrchr(prg_name, '/');
256 	if (s != NULL && *++s != '\0')
257 	prg_name = s;
258 
259 	term = getenv("TERM");
260 
261 	while ((c = getopt (argc, argv, "ST:")) != EOF)
262 	    switch (c)
263 	    {
264 	    case 'S':
265 		cmdline = 0;
266 		break;
267 	    case 'T':
268 		use_env(FALSE);
269 		term = optarg;
270 		break;
271 	    default:
272 		usage();
273 		/* NOTREACHED */
274 	    }
275 	argc -= optind;
276 	argv += optind;
277 
278 	if (cmdline && argc == 0) {
279 		usage();
280 		/* NOTREACHED */
281 	}
282 
283 	if (term == NULL || *term == '\0')
284 		quit(2, "No value for $TERM and no -T specified");
285 
286 	if (setupterm(term, STDOUT_FILENO, &errret) != OK && errret <= 0)
287 		quit(3, "unknown terminal \"%s\"", term);
288 
289 	if (cmdline)
290 		return tput(argc, argv);
291 
292 	while (fgets(buf, sizeof(buf), stdin) != (char *)NULL) {
293 		char	*argvec[16];	/* command, 9 parms, null, & slop */
294 		int	 argnum = 0;
295 		char    *cp;
296 
297 		/* crack the argument list into a dope vector */
298 		for (cp = buf; *cp; cp++) {
299 			if (isspace(*cp))
300 				*cp = '\0';
301 			else if (cp == buf || cp[-1] == 0)
302 				argvec[argnum++] = cp;
303 		}
304 		argvec[argnum] = (char *)NULL;
305 
306 		if (tput(argnum, argvec) != 0)
307 			errors++;
308 	}
309 
310 	return errors > 0;
311 }
312 
313