tput.c revision 62449
190075Sobrien/****************************************************************************
2119256Skan * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc.                        *
390075Sobrien *                                                                          *
490075Sobrien * Permission is hereby granted, free of charge, to any person obtaining a  *
590075Sobrien * copy of this software and associated documentation files (the            *
690075Sobrien * "Software"), to deal in the Software without restriction, including      *
790075Sobrien * without limitation the rights to use, copy, modify, merge, publish,      *
890075Sobrien * distribute, distribute with modifications, sublicense, and/or sell       *
990075Sobrien * copies of the Software, and to permit persons to whom the Software is    *
1090075Sobrien * furnished to do so, subject to the following conditions:                 *
1190075Sobrien *                                                                          *
1290075Sobrien * The above copyright notice and this permission notice shall be included  *
1390075Sobrien * in all copies or substantial portions of the Software.                   *
1490075Sobrien *                                                                          *
1590075Sobrien * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
16132718Skan * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
17132718Skan * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
1890075Sobrien * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
1990075Sobrien * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
2090075Sobrien * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
2190075Sobrien * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
2290075Sobrien *                                                                          *
2390075Sobrien * Except as contained in this notice, the name(s) of the above copyright   *
2490075Sobrien * holders shall not be used in advertising or otherwise to promote the     *
2590075Sobrien * sale, use or other dealings in this Software without prior written       *
2690075Sobrien * authorization.                                                           *
2790075Sobrien ****************************************************************************/
2890075Sobrien
2990075Sobrien/****************************************************************************
3090075Sobrien *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
3190075Sobrien *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
3290075Sobrien ****************************************************************************/
3390075Sobrien
3490075Sobrien/*
3590075Sobrien * tput.c -- shellscript access to terminal capabilities
3690075Sobrien *
3790075Sobrien * by Eric S. Raymond <esr@snark.thyrsus.com>, portions based on code from
3890075Sobrien * Ross Ridge's mytinfo package.
3990075Sobrien */
4090075Sobrien
4190075Sobrien#include <progs.priv.h>
4290075Sobrien#ifndef	PURE_TERMINFO
4390075Sobrien#include <termsort.c>
4490075Sobrien#endif
4590075Sobrien
4690075SobrienMODULE_ID("$Id: tput.c,v 1.16 2000/03/19 01:08:08 tom Exp $")
4790075Sobrien
4890075Sobrien#define PUTS(s)		fputs(s, stdout)
4990075Sobrien#define PUTCHAR(c)	putchar(c)
5090075Sobrien#define FLUSH		fflush(stdout)
5190075Sobrien
5290075Sobrienstatic char *prg_name;
5390075Sobrien
5490075Sobrienstatic void
5590075Sobrienquit(int status, const char *fmt,...)
5690075Sobrien{
5790075Sobrien    va_list argp;
5890075Sobrien
5990075Sobrien    va_start(argp, fmt);
6090075Sobrien    vfprintf(stderr, fmt, argp);
6190075Sobrien    fprintf(stderr, "\n");
6290075Sobrien    va_end(argp);
6390075Sobrien    exit(status);
6490075Sobrien}
6590075Sobrien
6690075Sobrienstatic void
6790075Sobrienusage(void)
6890075Sobrien{
6990075Sobrien    fprintf(stderr, "usage: %s [-S] [-T term] capname\n", prg_name);
7090075Sobrien    exit(EXIT_FAILURE);
7190075Sobrien}
7290075Sobrien
7390075Sobrienstatic int
7490075Sobrientput(int argc, char *argv[])
7590075Sobrien{
7690075Sobrien    NCURSES_CONST char *name;
7790075Sobrien    char *s;
7890075Sobrien    int i, j, c;
7990075Sobrien    int reset, status;
8090075Sobrien    FILE *f;
8190075Sobrien
8290075Sobrien    reset = 0;
8390075Sobrien    name = argv[0];
8490075Sobrien    if (strcmp(name, "reset") == 0) {
8590075Sobrien	reset = 1;
8690075Sobrien    }
8790075Sobrien    if (reset || strcmp(name, "init") == 0) {
8890075Sobrien	if (init_prog != 0) {
8990075Sobrien	    system(init_prog);
9090075Sobrien	}
9190075Sobrien	FLUSH;
9290075Sobrien
9390075Sobrien	if (reset && reset_1string != 0) {
9490075Sobrien	    PUTS(reset_1string);
9590075Sobrien	} else if (init_1string != 0) {
9690075Sobrien	    PUTS(init_1string);
9790075Sobrien	}
9890075Sobrien	FLUSH;
9990075Sobrien
10090075Sobrien	if (reset && reset_2string != 0) {
10190075Sobrien	    PUTS(reset_2string);
10290075Sobrien	} else if (init_2string != 0) {
10390075Sobrien	    PUTS(init_2string);
10490075Sobrien	}
10590075Sobrien	FLUSH;
10690075Sobrien
10790075Sobrien	if (set_lr_margin != 0) {
10890075Sobrien	    PUTS(tparm(set_lr_margin, 0, columns - 1));
10990075Sobrien	} else if (set_left_margin_parm != 0
11090075Sobrien	    && set_right_margin_parm != 0) {
11190075Sobrien	    PUTS(tparm(set_left_margin_parm, 0));
11290075Sobrien	    PUTS(tparm(set_right_margin_parm, columns - 1));
11390075Sobrien	} else if (clear_margins != 0
11490075Sobrien	    && set_left_margin != 0
11590075Sobrien	    && set_right_margin != 0) {
11690075Sobrien	    PUTS(clear_margins);
11790075Sobrien	    if (carriage_return != 0) {
11890075Sobrien		PUTS(carriage_return);
11990075Sobrien	    } else {
12090075Sobrien		PUTCHAR('\r');
12190075Sobrien	    }
12290075Sobrien	    PUTS(set_left_margin);
12390075Sobrien	    if (parm_right_cursor) {
12490075Sobrien		PUTS(tparm(parm_right_cursor, columns - 1));
12590075Sobrien	    } else {
12690075Sobrien		for (i = 0; i < columns - 1; i++) {
12790075Sobrien		    PUTCHAR(' ');
12890075Sobrien		}
12990075Sobrien	    }
13090075Sobrien	    PUTS(set_right_margin);
13190075Sobrien	    if (carriage_return != 0) {
13290075Sobrien		PUTS(carriage_return);
13390075Sobrien	    } else {
13490075Sobrien		PUTCHAR('\r');
13590075Sobrien	    }
13690075Sobrien	}
13790075Sobrien	FLUSH;
138119256Skan
139119256Skan	if (init_tabs != 8) {
140119256Skan	    if (clear_all_tabs != 0 && set_tab != 0) {
141119256Skan		for (i = 0; i < columns - 1; i += 8) {
14290075Sobrien		    if (parm_right_cursor) {
143119256Skan			PUTS(tparm(parm_right_cursor, 8));
14490075Sobrien		    } else {
14590075Sobrien			for (j = 0; j < 8; j++)
14690075Sobrien			    PUTCHAR(' ');
14790075Sobrien		    }
14890075Sobrien		    PUTS(set_tab);
14990075Sobrien		}
15090075Sobrien		FLUSH;
151119256Skan	    }
152119256Skan	}
153119256Skan
154119256Skan	if (reset && reset_file != 0) {
155119256Skan	    f = fopen(reset_file, "r");
156119256Skan	    if (f == 0) {
157119256Skan		quit(errno, "Can't open reset_file: '%s'", reset_file);
158119256Skan	    }
159119256Skan	    while ((c = fgetc(f)) != EOF) {
160119256Skan		PUTCHAR(c);
161119256Skan	    }
162119256Skan	    fclose(f);
163119256Skan	} else if (init_file != 0) {
164119256Skan	    f = fopen(init_file, "r");
165119256Skan	    if (f == 0) {
166119256Skan		quit(errno, "Can't open init_file: '%s'", init_file);
167119256Skan	    }
168119256Skan	    while ((c = fgetc(f)) != EOF) {
16990075Sobrien		PUTCHAR(c);
17090075Sobrien	    }
17190075Sobrien	    fclose(f);
17290075Sobrien	}
17390075Sobrien	FLUSH;
17490075Sobrien
17590075Sobrien	if (reset && reset_3string != 0) {
17690075Sobrien	    PUTS(reset_3string);
17790075Sobrien	} else if (init_2string != 0) {
17890075Sobrien	    PUTS(init_2string);
17990075Sobrien	}
18090075Sobrien	FLUSH;
18190075Sobrien	return 0;
18290075Sobrien    }
18390075Sobrien
18490075Sobrien    if (strcmp(name, "longname") == 0) {
18590075Sobrien	PUTS(longname());
18690075Sobrien	return 0;
18790075Sobrien    }
18890075Sobrien#ifndef	PURE_TERMINFO
18990075Sobrien    {
19090075Sobrien	const struct name_table_entry *np;
19190075Sobrien
19290075Sobrien	if ((np = _nc_find_entry(name, _nc_get_hash_table(1))) != 0)
19390075Sobrien	    switch (np->nte_type) {
19490075Sobrien	    case BOOLEAN:
19590075Sobrien		if (bool_from_termcap[np->nte_index])
19690075Sobrien		    name = boolnames[np->nte_index];
19790075Sobrien		break;
19890075Sobrien
19990075Sobrien	    case NUMBER:
20090075Sobrien		if (num_from_termcap[np->nte_index])
20190075Sobrien		    name = numnames[np->nte_index];
20290075Sobrien		break;
20390075Sobrien
20490075Sobrien	    case STRING:
20590075Sobrien		if (str_from_termcap[np->nte_index])
20690075Sobrien		    name = strnames[np->nte_index];
20790075Sobrien		break;
20890075Sobrien	    }
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