tput.c revision 62449
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
46MODULE_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
52static char *prg_name;
53
54static void
55quit(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
66static void
67usage(void)
68{
69    fprintf(stderr, "usage: %s [-S] [-T term] capname\n", prg_name);
70    exit(EXIT_FAILURE);
71}
72
73static int
74tput(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
253int
254main(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