xref: /freebsd/contrib/ncurses/progs/tput.c (revision b601c69bdbe8755d26570261d7fd4c02ee4eff74)
1 /****************************************************************************
2  * Copyright (c) 1998,1999,2000 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  * tput.c -- shellscript access to terminal capabilities
36  *
37  * by Eric S. Raymond <esr@snark.thyrsus.com>, portions based on code from
38  * Ross Ridge's mytinfo package.
39  */
40 
41 #include <progs.priv.h>
42 #ifndef	PURE_TERMINFO
43 #include <termsort.c>
44 #endif
45 
46 MODULE_ID("$Id: tput.c,v 1.16 2000/03/19 01:08:08 tom Exp $")
47 
48 #define PUTS(s)		fputs(s, stdout)
49 #define PUTCHAR(c)	putchar(c)
50 #define FLUSH		fflush(stdout)
51 
52 static char *prg_name;
53 
54 static void
55 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
67 usage(void)
68 {
69     fprintf(stderr, "usage: %s [-S] [-T term] capname\n", prg_name);
70     exit(EXIT_FAILURE);
71 }
72 
73 static int
74 tput(int argc, char *argv[])
75 {
76     NCURSES_CONST char *name;
77     char *s;
78     int i, j, c;
79     int reset, status;
80     FILE *f;
81 
82     reset = 0;
83     name = argv[0];
84     if (strcmp(name, "reset") == 0) {
85 	reset = 1;
86     }
87     if (reset || strcmp(name, "init") == 0) {
88 	if (init_prog != 0) {
89 	    system(init_prog);
90 	}
91 	FLUSH;
92 
93 	if (reset && reset_1string != 0) {
94 	    PUTS(reset_1string);
95 	} else if (init_1string != 0) {
96 	    PUTS(init_1string);
97 	}
98 	FLUSH;
99 
100 	if (reset && reset_2string != 0) {
101 	    PUTS(reset_2string);
102 	} else if (init_2string != 0) {
103 	    PUTS(init_2string);
104 	}
105 	FLUSH;
106 
107 	if (set_lr_margin != 0) {
108 	    PUTS(tparm(set_lr_margin, 0, columns - 1));
109 	} else if (set_left_margin_parm != 0
110 	    && set_right_margin_parm != 0) {
111 	    PUTS(tparm(set_left_margin_parm, 0));
112 	    PUTS(tparm(set_right_margin_parm, columns - 1));
113 	} else if (clear_margins != 0
114 	    && set_left_margin != 0
115 	    && set_right_margin != 0) {
116 	    PUTS(clear_margins);
117 	    if (carriage_return != 0) {
118 		PUTS(carriage_return);
119 	    } else {
120 		PUTCHAR('\r');
121 	    }
122 	    PUTS(set_left_margin);
123 	    if (parm_right_cursor) {
124 		PUTS(tparm(parm_right_cursor, columns - 1));
125 	    } else {
126 		for (i = 0; i < columns - 1; i++) {
127 		    PUTCHAR(' ');
128 		}
129 	    }
130 	    PUTS(set_right_margin);
131 	    if (carriage_return != 0) {
132 		PUTS(carriage_return);
133 	    } else {
134 		PUTCHAR('\r');
135 	    }
136 	}
137 	FLUSH;
138 
139 	if (init_tabs != 8) {
140 	    if (clear_all_tabs != 0 && set_tab != 0) {
141 		for (i = 0; i < columns - 1; i += 8) {
142 		    if (parm_right_cursor) {
143 			PUTS(tparm(parm_right_cursor, 8));
144 		    } else {
145 			for (j = 0; j < 8; j++)
146 			    PUTCHAR(' ');
147 		    }
148 		    PUTS(set_tab);
149 		}
150 		FLUSH;
151 	    }
152 	}
153 
154 	if (reset && reset_file != 0) {
155 	    f = fopen(reset_file, "r");
156 	    if (f == 0) {
157 		quit(errno, "Can't open reset_file: '%s'", reset_file);
158 	    }
159 	    while ((c = fgetc(f)) != EOF) {
160 		PUTCHAR(c);
161 	    }
162 	    fclose(f);
163 	} else if (init_file != 0) {
164 	    f = fopen(init_file, "r");
165 	    if (f == 0) {
166 		quit(errno, "Can't open init_file: '%s'", init_file);
167 	    }
168 	    while ((c = fgetc(f)) != EOF) {
169 		PUTCHAR(c);
170 	    }
171 	    fclose(f);
172 	}
173 	FLUSH;
174 
175 	if (reset && reset_3string != 0) {
176 	    PUTS(reset_3string);
177 	} else if (init_2string != 0) {
178 	    PUTS(init_2string);
179 	}
180 	FLUSH;
181 	return 0;
182     }
183 
184     if (strcmp(name, "longname") == 0) {
185 	PUTS(longname());
186 	return 0;
187     }
188 #ifndef	PURE_TERMINFO
189     {
190 	const struct name_table_entry *np;
191 
192 	if ((np = _nc_find_entry(name, _nc_get_hash_table(1))) != 0)
193 	    switch (np->nte_type) {
194 	    case BOOLEAN:
195 		if (bool_from_termcap[np->nte_index])
196 		    name = boolnames[np->nte_index];
197 		break;
198 
199 	    case NUMBER:
200 		if (num_from_termcap[np->nte_index])
201 		    name = numnames[np->nte_index];
202 		break;
203 
204 	    case STRING:
205 		if (str_from_termcap[np->nte_index])
206 		    name = strnames[np->nte_index];
207 		break;
208 	    }
209     }
210 #endif
211 
212     if ((status = tigetflag(name)) != -1) {
213 	return (status != 0);
214     } else if ((status = tigetnum(name)) != CANCELLED_NUMERIC) {
215 	(void) printf("%d\n", status);
216 	return (0);
217     } else if ((s = tigetstr(name)) == CANCELLED_STRING) {
218 	quit(4, "%s: unknown terminfo capability '%s'", prg_name, name);
219     } else if (s != 0) {
220 	if (argc > 1) {
221 	    int k;
222 	    char * params[10];
223 
224 	    /* Nasty hack time. The tparm function needs to see numeric
225 	     * parameters as numbers, not as pointers to their string
226 	     * representations
227 	     */
228 
229 	    for (k = 1; k < argc; k++) {
230 		if (isdigit(argv[k][0])) {
231 		    long val = atol(argv[k]);
232 		    params[k] = (char *)val;
233 		} else {
234 		    params[k] = argv[k];
235 		}
236 	    }
237 	    for (k = argc; k <= 9; k++)
238 		params[k] = 0;
239 
240 	    s = tparm(s,
241 	    	params[1], params[2], params[3],
242 		params[4], params[5], params[6],
243 		params[7], params[8], params[9]);
244 	}
245 
246 	/* use putp() in order to perform padding */
247 	putp(s);
248 	return (0);
249     }
250     return (0);
251 }
252 
253 int
254 main(int argc, char **argv)
255 {
256     char *s, *term;
257     int errret, cmdline = 1;
258     int c;
259     char buf[BUFSIZ];
260     int errors = 0;
261 
262     prg_name = argv[0];
263     s = strrchr(prg_name, '/');
264     if (s != 0 && *++s != '\0')
265 	prg_name = s;
266 
267     term = getenv("TERM");
268 
269     while ((c = getopt(argc, argv, "ST:")) != EOF)
270 	switch (c) {
271 	case 'S':
272 	    cmdline = 0;
273 	    break;
274 	case 'T':
275 	    use_env(FALSE);
276 	    term = optarg;
277 	    break;
278 	default:
279 	    usage();
280 	    /* NOTREACHED */
281 	}
282     argc -= optind;
283     argv += optind;
284 
285     if (cmdline && argc == 0) {
286 	usage();
287 	/* NOTREACHED */
288     }
289 
290     if (term == 0 || *term == '\0')
291 	quit(2, "No value for $TERM and no -T specified");
292 
293     if (setupterm(term, STDOUT_FILENO, &errret) != OK && errret <= 0)
294 	quit(3, "unknown terminal \"%s\"", term);
295 
296     if (cmdline)
297 	return tput(argc, argv);
298 
299     while (fgets(buf, sizeof(buf), stdin) != 0) {
300 	char *argvec[16];	/* command, 9 parms, null, & slop */
301 	int argnum = 0;
302 	char *cp;
303 
304 	/* crack the argument list into a dope vector */
305 	for (cp = buf; *cp; cp++) {
306 	    if (isspace(*cp))
307 		*cp = '\0';
308 	    else if (cp == buf || cp[-1] == 0)
309 		argvec[argnum++] = cp;
310 	}
311 	argvec[argnum] = 0;
312 
313 	if (tput(argnum, argvec) != 0)
314 	    errors++;
315     }
316 
317     return errors > 0;
318 }
319