xref: /freebsd/contrib/ncurses/progs/tput.c (revision 0e3d540892016a47f6a68ec9ba2879d35ce5f7c2)
10e3d5408SPeter Wemm /****************************************************************************
20e3d5408SPeter Wemm  * Copyright (c) 1998 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 /*
360e3d5408SPeter Wemm  * tput.c -- shellscript access to terminal capabilities
370e3d5408SPeter Wemm  *
380e3d5408SPeter Wemm  * by Eric S. Raymond <esr@snark.thyrsus.com>, portions based on code from
390e3d5408SPeter Wemm  * Ross Ridge's mytinfo package.
400e3d5408SPeter Wemm  */
410e3d5408SPeter Wemm 
420e3d5408SPeter Wemm #include <progs.priv.h>
430e3d5408SPeter Wemm #ifndef	PURE_TERMINFO
440e3d5408SPeter Wemm #include <termsort.c>
450e3d5408SPeter Wemm #endif
460e3d5408SPeter Wemm 
470e3d5408SPeter Wemm MODULE_ID("$Id: tput.c,v 1.14 1999/07/31 21:18:29 Goran.Uddeborg Exp $")
480e3d5408SPeter Wemm 
490e3d5408SPeter Wemm #define PUTS(s)		fputs(s, stdout)
500e3d5408SPeter Wemm #define PUTCHAR(c)	putchar(c)
510e3d5408SPeter Wemm #define FLUSH		fflush(stdout)
520e3d5408SPeter Wemm 
530e3d5408SPeter Wemm static char *prg_name;
540e3d5408SPeter Wemm 
550e3d5408SPeter Wemm static void 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 
660e3d5408SPeter Wemm static void usage(void)
670e3d5408SPeter Wemm {
680e3d5408SPeter Wemm 	fprintf(stderr, "usage: %s [-S] [-T term] capname\n", prg_name);
690e3d5408SPeter Wemm 	exit(EXIT_FAILURE);
700e3d5408SPeter Wemm }
710e3d5408SPeter Wemm 
720e3d5408SPeter Wemm static int tput(int argc, char *argv[])
730e3d5408SPeter Wemm {
740e3d5408SPeter Wemm char *name;
750e3d5408SPeter Wemm char *s;
760e3d5408SPeter Wemm int i, j, c;
770e3d5408SPeter Wemm int reset, status;
780e3d5408SPeter Wemm FILE *f;
790e3d5408SPeter Wemm 
800e3d5408SPeter Wemm 	reset = 0;
810e3d5408SPeter Wemm 	name = argv[0];
820e3d5408SPeter Wemm 	if (strcmp(name, "reset") == 0) {
830e3d5408SPeter Wemm 		reset = 1;
840e3d5408SPeter Wemm 	}
850e3d5408SPeter Wemm 	if (reset || strcmp(name, "init") == 0) {
860e3d5408SPeter Wemm 		if (init_prog != NULL) {
870e3d5408SPeter Wemm 			system(init_prog);
880e3d5408SPeter Wemm 		}
890e3d5408SPeter Wemm 		FLUSH;
900e3d5408SPeter Wemm 
910e3d5408SPeter Wemm 		if (reset && reset_1string != NULL) {
920e3d5408SPeter Wemm 			PUTS(reset_1string);
930e3d5408SPeter Wemm 		} else if (init_1string != NULL) {
940e3d5408SPeter Wemm 			PUTS(init_1string);
950e3d5408SPeter Wemm 		}
960e3d5408SPeter Wemm 		FLUSH;
970e3d5408SPeter Wemm 
980e3d5408SPeter Wemm 		if (reset && reset_2string != NULL) {
990e3d5408SPeter Wemm 			PUTS(reset_2string);
1000e3d5408SPeter Wemm 		} else if (init_2string != NULL) {
1010e3d5408SPeter Wemm 			PUTS(init_2string);
1020e3d5408SPeter Wemm 		}
1030e3d5408SPeter Wemm 		FLUSH;
1040e3d5408SPeter Wemm 
1050e3d5408SPeter Wemm 		if (set_lr_margin != NULL) {
1060e3d5408SPeter Wemm 			PUTS(tparm(set_lr_margin, 0, columns - 1));
1070e3d5408SPeter Wemm 		} else if (set_left_margin_parm != NULL
1080e3d5408SPeter Wemm 			   && set_right_margin_parm != NULL) {
1090e3d5408SPeter Wemm 			PUTS(tparm(set_left_margin_parm, 0));
1100e3d5408SPeter Wemm 			PUTS(tparm(set_right_margin_parm, columns - 1));
1110e3d5408SPeter Wemm 		} else if (clear_margins != NULL && set_left_margin != NULL
1120e3d5408SPeter Wemm 			   && set_right_margin != NULL) {
1130e3d5408SPeter Wemm 			PUTS(clear_margins);
1140e3d5408SPeter Wemm 			if (carriage_return != NULL) {
1150e3d5408SPeter Wemm 				PUTS(carriage_return);
1160e3d5408SPeter Wemm 			} else {
1170e3d5408SPeter Wemm 				PUTCHAR('\r');
1180e3d5408SPeter Wemm 			}
1190e3d5408SPeter Wemm 			PUTS(set_left_margin);
1200e3d5408SPeter Wemm 			if (parm_right_cursor) {
1210e3d5408SPeter Wemm 				PUTS(tparm(parm_right_cursor, columns - 1));
1220e3d5408SPeter Wemm 			} else {
1230e3d5408SPeter Wemm 				for(i = 0; i < columns - 1; i++) {
1240e3d5408SPeter Wemm 					PUTCHAR(' ');
1250e3d5408SPeter Wemm 				}
1260e3d5408SPeter Wemm 			}
1270e3d5408SPeter Wemm 			PUTS(set_right_margin);
1280e3d5408SPeter Wemm 			if (carriage_return != NULL) {
1290e3d5408SPeter Wemm 				PUTS(carriage_return);
1300e3d5408SPeter Wemm 			} else {
1310e3d5408SPeter Wemm 				PUTCHAR('\r');
1320e3d5408SPeter Wemm 			}
1330e3d5408SPeter Wemm 		}
1340e3d5408SPeter Wemm 		FLUSH;
1350e3d5408SPeter Wemm 
1360e3d5408SPeter Wemm 		if (init_tabs != 8) {
1370e3d5408SPeter Wemm 			if (clear_all_tabs != NULL && set_tab != NULL) {
1380e3d5408SPeter Wemm 				for(i = 0; i < columns - 1; i += 8) {
1390e3d5408SPeter Wemm 					if (parm_right_cursor) {
1400e3d5408SPeter Wemm 						PUTS(tparm(parm_right_cursor, 8));
1410e3d5408SPeter Wemm 					} else {
1420e3d5408SPeter Wemm 						for(j = 0; j < 8; j++)
1430e3d5408SPeter Wemm 							PUTCHAR(' ');
1440e3d5408SPeter Wemm 					}
1450e3d5408SPeter Wemm 					PUTS(set_tab);
1460e3d5408SPeter Wemm 				}
1470e3d5408SPeter Wemm 				FLUSH;
1480e3d5408SPeter Wemm 			}
1490e3d5408SPeter Wemm 		}
1500e3d5408SPeter Wemm 
1510e3d5408SPeter Wemm 		if (reset && reset_file != NULL) {
1520e3d5408SPeter Wemm 			f = fopen(reset_file, "r");
1530e3d5408SPeter Wemm 			if (f == NULL) {
1540e3d5408SPeter Wemm 				quit(errno, "Can't open reset_file: '%s'", reset_file);
1550e3d5408SPeter Wemm 			}
1560e3d5408SPeter Wemm 			while((c = fgetc(f)) != EOF) {
1570e3d5408SPeter Wemm 				PUTCHAR(c);
1580e3d5408SPeter Wemm 			}
1590e3d5408SPeter Wemm 			fclose(f);
1600e3d5408SPeter Wemm 		} else if (init_file != NULL) {
1610e3d5408SPeter Wemm 			f = fopen(init_file, "r");
1620e3d5408SPeter Wemm 			if (f == NULL) {
1630e3d5408SPeter Wemm 				quit(errno, "Can't open init_file: '%s'", init_file);
1640e3d5408SPeter Wemm 			}
1650e3d5408SPeter Wemm 			while((c = fgetc(f)) != EOF) {
1660e3d5408SPeter Wemm 				PUTCHAR(c);
1670e3d5408SPeter Wemm 			}
1680e3d5408SPeter Wemm 			fclose(f);
1690e3d5408SPeter Wemm 		}
1700e3d5408SPeter Wemm 		FLUSH;
1710e3d5408SPeter Wemm 
1720e3d5408SPeter Wemm 		if (reset && reset_3string != NULL) {
1730e3d5408SPeter Wemm 			PUTS(reset_3string);
1740e3d5408SPeter Wemm 		} else if (init_2string != NULL) {
1750e3d5408SPeter Wemm 			PUTS(init_2string);
1760e3d5408SPeter Wemm 		}
1770e3d5408SPeter Wemm 		FLUSH;
1780e3d5408SPeter Wemm 		return 0;
1790e3d5408SPeter Wemm 	}
1800e3d5408SPeter Wemm 
1810e3d5408SPeter Wemm 	if (strcmp(name, "longname") == 0) {
1820e3d5408SPeter Wemm 		PUTS(longname());
1830e3d5408SPeter Wemm 		return 0;
1840e3d5408SPeter Wemm 	}
1850e3d5408SPeter Wemm 
1860e3d5408SPeter Wemm #ifndef	PURE_TERMINFO
1870e3d5408SPeter Wemm 	{
1880e3d5408SPeter Wemm 		const struct name_table_entry 	*np;
1890e3d5408SPeter Wemm 
1900e3d5408SPeter Wemm 		if ((np = _nc_find_entry(name, _nc_get_hash_table(1))) != 0)
1910e3d5408SPeter Wemm 			switch(np->nte_type)
1920e3d5408SPeter Wemm 			{
1930e3d5408SPeter Wemm 			case BOOLEAN:
1940e3d5408SPeter Wemm 				if (bool_from_termcap[np->nte_index])
1950e3d5408SPeter Wemm 					name = boolnames[np->nte_index];
1960e3d5408SPeter Wemm 				break;
1970e3d5408SPeter Wemm 
1980e3d5408SPeter Wemm 			case NUMBER:
1990e3d5408SPeter Wemm 				if (num_from_termcap[np->nte_index])
2000e3d5408SPeter Wemm 					name = numnames[np->nte_index];
2010e3d5408SPeter Wemm 				break;
2020e3d5408SPeter Wemm 
2030e3d5408SPeter Wemm 			case STRING:
2040e3d5408SPeter Wemm 				if (str_from_termcap[np->nte_index])
2050e3d5408SPeter Wemm 					name = strnames[np->nte_index];
2060e3d5408SPeter Wemm 				break;
2070e3d5408SPeter Wemm 			}
2080e3d5408SPeter Wemm 	}
2090e3d5408SPeter Wemm #endif
2100e3d5408SPeter Wemm 
2110e3d5408SPeter Wemm 	if ((status = tigetflag(name)) != -1)
2120e3d5408SPeter Wemm 		return(status != 0);
2130e3d5408SPeter Wemm 	else if ((status = tigetnum(name)) != CANCELLED_NUMERIC) {
2140e3d5408SPeter Wemm 		(void) printf("%d\n", status);
2150e3d5408SPeter Wemm 		return(0);
2160e3d5408SPeter Wemm 	}
2170e3d5408SPeter Wemm 	else if ((s = tigetstr(name)) == CANCELLED_STRING)
2180e3d5408SPeter Wemm 		quit(4, "%s: unknown terminfo capability '%s'", prg_name, name);
2190e3d5408SPeter Wemm 	else if (s != (char *)NULL) {
2200e3d5408SPeter Wemm 		if (argc > 1) {
2210e3d5408SPeter Wemm 		int k;
2220e3d5408SPeter Wemm 
2230e3d5408SPeter Wemm 			/* Nasty hack time. The tparm function needs to see numeric
2240e3d5408SPeter Wemm 			 * parameters as numbers, not as pointers to their string
2250e3d5408SPeter Wemm 			 * representations
2260e3d5408SPeter Wemm 			 */
2270e3d5408SPeter Wemm 
2280e3d5408SPeter Wemm 			 for (k = 1; k < argc; k++)
2290e3d5408SPeter Wemm 			 	if (isdigit(argv[k][0])) {
2300e3d5408SPeter Wemm 			 		long val = atol(argv[k]);
2310e3d5408SPeter Wemm 			 		argv[k] = (char *)val;
2320e3d5408SPeter Wemm 				}
2330e3d5408SPeter Wemm 
2340e3d5408SPeter Wemm 				s = tparm(s,argv[1],argv[2],argv[3],argv[4],
2350e3d5408SPeter Wemm 					    argv[5],argv[6],argv[7],argv[8],
2360e3d5408SPeter Wemm 					    argv[9]);
2370e3d5408SPeter Wemm 		}
2380e3d5408SPeter Wemm 
2390e3d5408SPeter Wemm 		/* use putp() in order to perform padding */
2400e3d5408SPeter Wemm 		putp(s);
2410e3d5408SPeter Wemm 		return(0);
2420e3d5408SPeter Wemm 	}
2430e3d5408SPeter Wemm 	return(0);
2440e3d5408SPeter Wemm }
2450e3d5408SPeter Wemm 
2460e3d5408SPeter Wemm int main(int argc, char **argv)
2470e3d5408SPeter Wemm {
2480e3d5408SPeter Wemm char *s, *term;
2490e3d5408SPeter Wemm int errret, cmdline = 1;
2500e3d5408SPeter Wemm int c;
2510e3d5408SPeter Wemm char	buf[BUFSIZ];
2520e3d5408SPeter Wemm int errors = 0;
2530e3d5408SPeter Wemm 
2540e3d5408SPeter Wemm 	prg_name = argv[0];
2550e3d5408SPeter Wemm 	s = strrchr(prg_name, '/');
2560e3d5408SPeter Wemm 	if (s != NULL && *++s != '\0')
2570e3d5408SPeter Wemm 	prg_name = s;
2580e3d5408SPeter Wemm 
2590e3d5408SPeter Wemm 	term = getenv("TERM");
2600e3d5408SPeter Wemm 
2610e3d5408SPeter Wemm 	while ((c = getopt (argc, argv, "ST:")) != EOF)
2620e3d5408SPeter Wemm 	    switch (c)
2630e3d5408SPeter Wemm 	    {
2640e3d5408SPeter Wemm 	    case 'S':
2650e3d5408SPeter Wemm 		cmdline = 0;
2660e3d5408SPeter Wemm 		break;
2670e3d5408SPeter Wemm 	    case 'T':
2680e3d5408SPeter Wemm 		use_env(FALSE);
2690e3d5408SPeter Wemm 		term = optarg;
2700e3d5408SPeter Wemm 		break;
2710e3d5408SPeter Wemm 	    default:
2720e3d5408SPeter Wemm 		usage();
2730e3d5408SPeter Wemm 		/* NOTREACHED */
2740e3d5408SPeter Wemm 	    }
2750e3d5408SPeter Wemm 	argc -= optind;
2760e3d5408SPeter Wemm 	argv += optind;
2770e3d5408SPeter Wemm 
2780e3d5408SPeter Wemm 	if (cmdline && argc == 0) {
2790e3d5408SPeter Wemm 		usage();
2800e3d5408SPeter Wemm 		/* NOTREACHED */
2810e3d5408SPeter Wemm 	}
2820e3d5408SPeter Wemm 
2830e3d5408SPeter Wemm 	if (term == NULL || *term == '\0')
2840e3d5408SPeter Wemm 		quit(2, "No value for $TERM and no -T specified");
2850e3d5408SPeter Wemm 
2860e3d5408SPeter Wemm 	if (setupterm(term, STDOUT_FILENO, &errret) != OK && errret <= 0)
2870e3d5408SPeter Wemm 		quit(3, "unknown terminal \"%s\"", term);
2880e3d5408SPeter Wemm 
2890e3d5408SPeter Wemm 	if (cmdline)
2900e3d5408SPeter Wemm 		return tput(argc, argv);
2910e3d5408SPeter Wemm 
2920e3d5408SPeter Wemm 	while (fgets(buf, sizeof(buf), stdin) != (char *)NULL) {
2930e3d5408SPeter Wemm 		char	*argvec[16];	/* command, 9 parms, null, & slop */
2940e3d5408SPeter Wemm 		int	 argnum = 0;
2950e3d5408SPeter Wemm 		char    *cp;
2960e3d5408SPeter Wemm 
2970e3d5408SPeter Wemm 		/* crack the argument list into a dope vector */
2980e3d5408SPeter Wemm 		for (cp = buf; *cp; cp++) {
2990e3d5408SPeter Wemm 			if (isspace(*cp))
3000e3d5408SPeter Wemm 				*cp = '\0';
3010e3d5408SPeter Wemm 			else if (cp == buf || cp[-1] == 0)
3020e3d5408SPeter Wemm 				argvec[argnum++] = cp;
3030e3d5408SPeter Wemm 		}
3040e3d5408SPeter Wemm 		argvec[argnum] = (char *)NULL;
3050e3d5408SPeter Wemm 
3060e3d5408SPeter Wemm 		if (tput(argnum, argvec) != 0)
3070e3d5408SPeter Wemm 			errors++;
3080e3d5408SPeter Wemm 	}
3090e3d5408SPeter Wemm 
3100e3d5408SPeter Wemm 	return errors > 0;
3110e3d5408SPeter Wemm }
3120e3d5408SPeter Wemm 
313