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