xref: /freebsd/contrib/ncurses/progs/tput.c (revision 15589c42fa2774d2f8ee650f4f31eb8d3a861316)
10e3d5408SPeter Wemm /****************************************************************************
215589c42SPeter Wemm  * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc.                        *
30e3d5408SPeter Wemm  *                                                                          *
40e3d5408SPeter Wemm  * Permission is hereby granted, free of charge, to any person obtaining a  *
50e3d5408SPeter Wemm  * copy of this software and associated documentation files (the            *
60e3d5408SPeter Wemm  * "Software"), to deal in the Software without restriction, including      *
70e3d5408SPeter Wemm  * without limitation the rights to use, copy, modify, merge, publish,      *
80e3d5408SPeter Wemm  * distribute, distribute with modifications, sublicense, and/or sell       *
90e3d5408SPeter Wemm  * copies of the Software, and to permit persons to whom the Software is    *
100e3d5408SPeter Wemm  * furnished to do so, subject to the following conditions:                 *
110e3d5408SPeter Wemm  *                                                                          *
120e3d5408SPeter Wemm  * The above copyright notice and this permission notice shall be included  *
130e3d5408SPeter Wemm  * in all copies or substantial portions of the Software.                   *
140e3d5408SPeter Wemm  *                                                                          *
150e3d5408SPeter Wemm  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
160e3d5408SPeter Wemm  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
170e3d5408SPeter Wemm  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
180e3d5408SPeter Wemm  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
190e3d5408SPeter Wemm  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
200e3d5408SPeter Wemm  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
210e3d5408SPeter Wemm  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
220e3d5408SPeter Wemm  *                                                                          *
230e3d5408SPeter Wemm  * Except as contained in this notice, the name(s) of the above copyright   *
240e3d5408SPeter Wemm  * holders shall not be used in advertising or otherwise to promote the     *
250e3d5408SPeter Wemm  * sale, use or other dealings in this Software without prior written       *
260e3d5408SPeter Wemm  * authorization.                                                           *
270e3d5408SPeter Wemm  ****************************************************************************/
280e3d5408SPeter Wemm 
290e3d5408SPeter Wemm /****************************************************************************
300e3d5408SPeter Wemm  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
310e3d5408SPeter Wemm  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
320e3d5408SPeter Wemm  ****************************************************************************/
330e3d5408SPeter Wemm 
340e3d5408SPeter Wemm /*
350e3d5408SPeter Wemm  * tput.c -- shellscript access to terminal capabilities
360e3d5408SPeter Wemm  *
370e3d5408SPeter Wemm  * by Eric S. Raymond <esr@snark.thyrsus.com>, portions based on code from
380e3d5408SPeter Wemm  * Ross Ridge's mytinfo package.
390e3d5408SPeter Wemm  */
400e3d5408SPeter Wemm 
410e3d5408SPeter Wemm #include <progs.priv.h>
420e3d5408SPeter Wemm #ifndef	PURE_TERMINFO
430e3d5408SPeter Wemm #include <termsort.c>
440e3d5408SPeter Wemm #endif
450e3d5408SPeter Wemm 
4615589c42SPeter Wemm MODULE_ID("$Id: tput.c,v 1.16 2000/03/19 01:08:08 tom Exp $")
470e3d5408SPeter Wemm 
480e3d5408SPeter Wemm #define PUTS(s)		fputs(s, stdout)
490e3d5408SPeter Wemm #define PUTCHAR(c)	putchar(c)
500e3d5408SPeter Wemm #define FLUSH		fflush(stdout)
510e3d5408SPeter Wemm 
520e3d5408SPeter Wemm static char *prg_name;
530e3d5408SPeter Wemm 
5415589c42SPeter Wemm static void
5515589c42SPeter Wemm quit(int status, const char *fmt,...)
560e3d5408SPeter Wemm {
570e3d5408SPeter Wemm     va_list argp;
580e3d5408SPeter Wemm 
590e3d5408SPeter Wemm     va_start(argp, fmt);
600e3d5408SPeter Wemm     vfprintf(stderr, fmt, argp);
610e3d5408SPeter Wemm     fprintf(stderr, "\n");
620e3d5408SPeter Wemm     va_end(argp);
630e3d5408SPeter Wemm     exit(status);
640e3d5408SPeter Wemm }
650e3d5408SPeter Wemm 
6615589c42SPeter Wemm static void
6715589c42SPeter Wemm usage(void)
680e3d5408SPeter Wemm {
690e3d5408SPeter Wemm     fprintf(stderr, "usage: %s [-S] [-T term] capname\n", prg_name);
700e3d5408SPeter Wemm     exit(EXIT_FAILURE);
710e3d5408SPeter Wemm }
720e3d5408SPeter Wemm 
7315589c42SPeter Wemm static int
7415589c42SPeter Wemm tput(int argc, char *argv[])
750e3d5408SPeter Wemm {
7615589c42SPeter Wemm     NCURSES_CONST char *name;
770e3d5408SPeter Wemm     char *s;
780e3d5408SPeter Wemm     int i, j, c;
790e3d5408SPeter Wemm     int reset, status;
800e3d5408SPeter Wemm     FILE *f;
810e3d5408SPeter Wemm 
820e3d5408SPeter Wemm     reset = 0;
830e3d5408SPeter Wemm     name = argv[0];
840e3d5408SPeter Wemm     if (strcmp(name, "reset") == 0) {
850e3d5408SPeter Wemm 	reset = 1;
860e3d5408SPeter Wemm     }
870e3d5408SPeter Wemm     if (reset || strcmp(name, "init") == 0) {
8815589c42SPeter Wemm 	if (init_prog != 0) {
890e3d5408SPeter Wemm 	    system(init_prog);
900e3d5408SPeter Wemm 	}
910e3d5408SPeter Wemm 	FLUSH;
920e3d5408SPeter Wemm 
9315589c42SPeter Wemm 	if (reset && reset_1string != 0) {
940e3d5408SPeter Wemm 	    PUTS(reset_1string);
9515589c42SPeter Wemm 	} else if (init_1string != 0) {
960e3d5408SPeter Wemm 	    PUTS(init_1string);
970e3d5408SPeter Wemm 	}
980e3d5408SPeter Wemm 	FLUSH;
990e3d5408SPeter Wemm 
10015589c42SPeter Wemm 	if (reset && reset_2string != 0) {
1010e3d5408SPeter Wemm 	    PUTS(reset_2string);
10215589c42SPeter Wemm 	} else if (init_2string != 0) {
1030e3d5408SPeter Wemm 	    PUTS(init_2string);
1040e3d5408SPeter Wemm 	}
1050e3d5408SPeter Wemm 	FLUSH;
1060e3d5408SPeter Wemm 
10715589c42SPeter Wemm 	if (set_lr_margin != 0) {
1080e3d5408SPeter Wemm 	    PUTS(tparm(set_lr_margin, 0, columns - 1));
10915589c42SPeter Wemm 	} else if (set_left_margin_parm != 0
11015589c42SPeter Wemm 	    && set_right_margin_parm != 0) {
1110e3d5408SPeter Wemm 	    PUTS(tparm(set_left_margin_parm, 0));
1120e3d5408SPeter Wemm 	    PUTS(tparm(set_right_margin_parm, columns - 1));
11315589c42SPeter Wemm 	} else if (clear_margins != 0
11415589c42SPeter Wemm 	    && set_left_margin != 0
11515589c42SPeter Wemm 	    && set_right_margin != 0) {
1160e3d5408SPeter Wemm 	    PUTS(clear_margins);
11715589c42SPeter Wemm 	    if (carriage_return != 0) {
1180e3d5408SPeter Wemm 		PUTS(carriage_return);
1190e3d5408SPeter Wemm 	    } else {
1200e3d5408SPeter Wemm 		PUTCHAR('\r');
1210e3d5408SPeter Wemm 	    }
1220e3d5408SPeter Wemm 	    PUTS(set_left_margin);
1230e3d5408SPeter Wemm 	    if (parm_right_cursor) {
1240e3d5408SPeter Wemm 		PUTS(tparm(parm_right_cursor, columns - 1));
1250e3d5408SPeter Wemm 	    } else {
1260e3d5408SPeter Wemm 		for (i = 0; i < columns - 1; i++) {
1270e3d5408SPeter Wemm 		    PUTCHAR(' ');
1280e3d5408SPeter Wemm 		}
1290e3d5408SPeter Wemm 	    }
1300e3d5408SPeter Wemm 	    PUTS(set_right_margin);
13115589c42SPeter Wemm 	    if (carriage_return != 0) {
1320e3d5408SPeter Wemm 		PUTS(carriage_return);
1330e3d5408SPeter Wemm 	    } else {
1340e3d5408SPeter Wemm 		PUTCHAR('\r');
1350e3d5408SPeter Wemm 	    }
1360e3d5408SPeter Wemm 	}
1370e3d5408SPeter Wemm 	FLUSH;
1380e3d5408SPeter Wemm 
1390e3d5408SPeter Wemm 	if (init_tabs != 8) {
14015589c42SPeter Wemm 	    if (clear_all_tabs != 0 && set_tab != 0) {
1410e3d5408SPeter Wemm 		for (i = 0; i < columns - 1; i += 8) {
1420e3d5408SPeter Wemm 		    if (parm_right_cursor) {
1430e3d5408SPeter Wemm 			PUTS(tparm(parm_right_cursor, 8));
1440e3d5408SPeter Wemm 		    } else {
1450e3d5408SPeter Wemm 			for (j = 0; j < 8; j++)
1460e3d5408SPeter Wemm 			    PUTCHAR(' ');
1470e3d5408SPeter Wemm 		    }
1480e3d5408SPeter Wemm 		    PUTS(set_tab);
1490e3d5408SPeter Wemm 		}
1500e3d5408SPeter Wemm 		FLUSH;
1510e3d5408SPeter Wemm 	    }
1520e3d5408SPeter Wemm 	}
1530e3d5408SPeter Wemm 
15415589c42SPeter Wemm 	if (reset && reset_file != 0) {
1550e3d5408SPeter Wemm 	    f = fopen(reset_file, "r");
15615589c42SPeter Wemm 	    if (f == 0) {
1570e3d5408SPeter Wemm 		quit(errno, "Can't open reset_file: '%s'", reset_file);
1580e3d5408SPeter Wemm 	    }
1590e3d5408SPeter Wemm 	    while ((c = fgetc(f)) != EOF) {
1600e3d5408SPeter Wemm 		PUTCHAR(c);
1610e3d5408SPeter Wemm 	    }
1620e3d5408SPeter Wemm 	    fclose(f);
16315589c42SPeter Wemm 	} else if (init_file != 0) {
1640e3d5408SPeter Wemm 	    f = fopen(init_file, "r");
16515589c42SPeter Wemm 	    if (f == 0) {
1660e3d5408SPeter Wemm 		quit(errno, "Can't open init_file: '%s'", init_file);
1670e3d5408SPeter Wemm 	    }
1680e3d5408SPeter Wemm 	    while ((c = fgetc(f)) != EOF) {
1690e3d5408SPeter Wemm 		PUTCHAR(c);
1700e3d5408SPeter Wemm 	    }
1710e3d5408SPeter Wemm 	    fclose(f);
1720e3d5408SPeter Wemm 	}
1730e3d5408SPeter Wemm 	FLUSH;
1740e3d5408SPeter Wemm 
17515589c42SPeter Wemm 	if (reset && reset_3string != 0) {
1760e3d5408SPeter Wemm 	    PUTS(reset_3string);
17715589c42SPeter Wemm 	} else if (init_2string != 0) {
1780e3d5408SPeter Wemm 	    PUTS(init_2string);
1790e3d5408SPeter Wemm 	}
1800e3d5408SPeter Wemm 	FLUSH;
1810e3d5408SPeter Wemm 	return 0;
1820e3d5408SPeter Wemm     }
1830e3d5408SPeter Wemm 
1840e3d5408SPeter Wemm     if (strcmp(name, "longname") == 0) {
1850e3d5408SPeter Wemm 	PUTS(longname());
1860e3d5408SPeter Wemm 	return 0;
1870e3d5408SPeter Wemm     }
1880e3d5408SPeter Wemm #ifndef	PURE_TERMINFO
1890e3d5408SPeter Wemm     {
1900e3d5408SPeter Wemm 	const struct name_table_entry *np;
1910e3d5408SPeter Wemm 
1920e3d5408SPeter Wemm 	if ((np = _nc_find_entry(name, _nc_get_hash_table(1))) != 0)
19315589c42SPeter Wemm 	    switch (np->nte_type) {
1940e3d5408SPeter Wemm 	    case BOOLEAN:
1950e3d5408SPeter Wemm 		if (bool_from_termcap[np->nte_index])
1960e3d5408SPeter Wemm 		    name = boolnames[np->nte_index];
1970e3d5408SPeter Wemm 		break;
1980e3d5408SPeter Wemm 
1990e3d5408SPeter Wemm 	    case NUMBER:
2000e3d5408SPeter Wemm 		if (num_from_termcap[np->nte_index])
2010e3d5408SPeter Wemm 		    name = numnames[np->nte_index];
2020e3d5408SPeter Wemm 		break;
2030e3d5408SPeter Wemm 
2040e3d5408SPeter Wemm 	    case STRING:
2050e3d5408SPeter Wemm 		if (str_from_termcap[np->nte_index])
2060e3d5408SPeter Wemm 		    name = strnames[np->nte_index];
2070e3d5408SPeter Wemm 		break;
2080e3d5408SPeter Wemm 	    }
2090e3d5408SPeter Wemm     }
2100e3d5408SPeter Wemm #endif
2110e3d5408SPeter Wemm 
21215589c42SPeter Wemm     if ((status = tigetflag(name)) != -1) {
2130e3d5408SPeter Wemm 	return (status != 0);
21415589c42SPeter Wemm     } else if ((status = tigetnum(name)) != CANCELLED_NUMERIC) {
2150e3d5408SPeter Wemm 	(void) printf("%d\n", status);
2160e3d5408SPeter Wemm 	return (0);
21715589c42SPeter Wemm     } else if ((s = tigetstr(name)) == CANCELLED_STRING) {
2180e3d5408SPeter Wemm 	quit(4, "%s: unknown terminfo capability '%s'", prg_name, name);
21915589c42SPeter Wemm     } else if (s != 0) {
2200e3d5408SPeter Wemm 	if (argc > 1) {
2210e3d5408SPeter Wemm 	    int k;
22215589c42SPeter Wemm 	    char * params[10];
2230e3d5408SPeter Wemm 
2240e3d5408SPeter Wemm 	    /* Nasty hack time. The tparm function needs to see numeric
2250e3d5408SPeter Wemm 	     * parameters as numbers, not as pointers to their string
2260e3d5408SPeter Wemm 	     * representations
2270e3d5408SPeter Wemm 	     */
2280e3d5408SPeter Wemm 
22915589c42SPeter Wemm 	    for (k = 1; k < argc; k++) {
2300e3d5408SPeter Wemm 		if (isdigit(argv[k][0])) {
2310e3d5408SPeter Wemm 		    long val = atol(argv[k]);
23215589c42SPeter Wemm 		    params[k] = (char *)val;
23315589c42SPeter Wemm 		} else {
23415589c42SPeter Wemm 		    params[k] = argv[k];
2350e3d5408SPeter Wemm 		}
23615589c42SPeter Wemm 	    }
23715589c42SPeter Wemm 	    for (k = argc; k <= 9; k++)
23815589c42SPeter Wemm 		params[k] = 0;
2390e3d5408SPeter Wemm 
24015589c42SPeter Wemm 	    s = tparm(s,
24115589c42SPeter Wemm 	    	params[1], params[2], params[3],
24215589c42SPeter Wemm 		params[4], params[5], params[6],
24315589c42SPeter Wemm 		params[7], params[8], params[9]);
2440e3d5408SPeter Wemm 	}
2450e3d5408SPeter Wemm 
2460e3d5408SPeter Wemm 	/* use putp() in order to perform padding */
2470e3d5408SPeter Wemm 	putp(s);
2480e3d5408SPeter Wemm 	return (0);
2490e3d5408SPeter Wemm     }
2500e3d5408SPeter Wemm     return (0);
2510e3d5408SPeter Wemm }
2520e3d5408SPeter Wemm 
25315589c42SPeter Wemm int
25415589c42SPeter Wemm main(int argc, char **argv)
2550e3d5408SPeter Wemm {
2560e3d5408SPeter Wemm     char *s, *term;
2570e3d5408SPeter Wemm     int errret, cmdline = 1;
2580e3d5408SPeter Wemm     int c;
2590e3d5408SPeter Wemm     char buf[BUFSIZ];
2600e3d5408SPeter Wemm     int errors = 0;
2610e3d5408SPeter Wemm 
2620e3d5408SPeter Wemm     prg_name = argv[0];
2630e3d5408SPeter Wemm     s = strrchr(prg_name, '/');
26415589c42SPeter Wemm     if (s != 0 && *++s != '\0')
2650e3d5408SPeter Wemm 	prg_name = s;
2660e3d5408SPeter Wemm 
2670e3d5408SPeter Wemm     term = getenv("TERM");
2680e3d5408SPeter Wemm 
2690e3d5408SPeter Wemm     while ((c = getopt(argc, argv, "ST:")) != EOF)
27015589c42SPeter Wemm 	switch (c) {
2710e3d5408SPeter Wemm 	case 'S':
2720e3d5408SPeter Wemm 	    cmdline = 0;
2730e3d5408SPeter Wemm 	    break;
2740e3d5408SPeter Wemm 	case 'T':
2750e3d5408SPeter Wemm 	    use_env(FALSE);
2760e3d5408SPeter Wemm 	    term = optarg;
2770e3d5408SPeter Wemm 	    break;
2780e3d5408SPeter Wemm 	default:
2790e3d5408SPeter Wemm 	    usage();
2800e3d5408SPeter Wemm 	    /* NOTREACHED */
2810e3d5408SPeter Wemm 	}
2820e3d5408SPeter Wemm     argc -= optind;
2830e3d5408SPeter Wemm     argv += optind;
2840e3d5408SPeter Wemm 
2850e3d5408SPeter Wemm     if (cmdline && argc == 0) {
2860e3d5408SPeter Wemm 	usage();
2870e3d5408SPeter Wemm 	/* NOTREACHED */
2880e3d5408SPeter Wemm     }
2890e3d5408SPeter Wemm 
29015589c42SPeter Wemm     if (term == 0 || *term == '\0')
2910e3d5408SPeter Wemm 	quit(2, "No value for $TERM and no -T specified");
2920e3d5408SPeter Wemm 
2930e3d5408SPeter Wemm     if (setupterm(term, STDOUT_FILENO, &errret) != OK && errret <= 0)
2940e3d5408SPeter Wemm 	quit(3, "unknown terminal \"%s\"", term);
2950e3d5408SPeter Wemm 
2960e3d5408SPeter Wemm     if (cmdline)
2970e3d5408SPeter Wemm 	return tput(argc, argv);
2980e3d5408SPeter Wemm 
29915589c42SPeter Wemm     while (fgets(buf, sizeof(buf), stdin) != 0) {
3000e3d5408SPeter Wemm 	char *argvec[16];	/* command, 9 parms, null, & slop */
3010e3d5408SPeter Wemm 	int argnum = 0;
3020e3d5408SPeter Wemm 	char *cp;
3030e3d5408SPeter Wemm 
3040e3d5408SPeter Wemm 	/* crack the argument list into a dope vector */
3050e3d5408SPeter Wemm 	for (cp = buf; *cp; cp++) {
3060e3d5408SPeter Wemm 	    if (isspace(*cp))
3070e3d5408SPeter Wemm 		*cp = '\0';
3080e3d5408SPeter Wemm 	    else if (cp == buf || cp[-1] == 0)
3090e3d5408SPeter Wemm 		argvec[argnum++] = cp;
3100e3d5408SPeter Wemm 	}
31115589c42SPeter Wemm 	argvec[argnum] = 0;
3120e3d5408SPeter Wemm 
3130e3d5408SPeter Wemm 	if (tput(argnum, argvec) != 0)
3140e3d5408SPeter Wemm 	    errors++;
3150e3d5408SPeter Wemm     }
3160e3d5408SPeter Wemm 
3170e3d5408SPeter Wemm     return errors > 0;
3180e3d5408SPeter Wemm }
319