tput.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1996, by Sun Microsystems, Inc.
* All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* tput.c
*
* Copyright 1990, 1994 by Mortice Kern Systems Inc. All rights reserved.
*
* PORTABILITY:
* SVID 3 - fully
* POSIX.2a UPE - needs clarification between SVID 3 exit statues.
* In particular exit 1 and 4 for string capnames.
* not in XPG 3
*
* SYNOPSIS:
* tput [-T<term>] capname [parm1..parm9]
* tput [-T<term>] -S
*
* DESCRIPTION:
* tput lets you change your terminal's characteristics. The capname
* argument indicates how you want to change the characteristics.
* Some special capnames are:
*
* clear clear the screen
* init initialize terminal in an implemenation-defined way
* reset reset terminal in an implemenation-defined way
* longname print the full name of the ternminal (SVID)
*
* Other capnames are supported and may take from 0 to 9 parameters. A
* list of them can be found in the SVID 3, vol 3. (SVID)
*
* tput does its work by outputting approriate character sequences to the
* standard output. These character sequences are terminal-specific. If
* you specify -T <type>, tput assumes that your terminal has the
* specified type and will issue sequences appropriate to that terminal.
*
* If you do not specify -T, tput looks for an environment variable
* named TERM. If TERM exists, its value is assumed to give the terminal
* type. If TERM does not exist, tput assumes a default terminal type.
*
* The -S option allows more than one capability per invocation of tput.
* The capabilities must be passed to tput from the standard input instead
* of the comamnd line. Only one capname is allowed per line.
*
* EXIT STATUS
* tput may return the following status values:
*
* 0 Either a boolean capname is set true or a string capname was
* successfully written to the terminal.
*
* 1 No error message is printed. Returned if a boolean capname is
* false or a string capname is not defined for the terminal.(SVID)
*
* 2 Usage error.
*
* 3 Unknown terminal <term> or no terminfo database.
*
* 4 Unknown terminfo capability <capname>.
*
* >4 An error occured.
*
*
* NOTE 1: If the Caps file that describes the terminfo database changes
* then a new term.h will be required. See CURSES/tic related tools.
*
* NOTE 2: tput has knowledge about the TERMINAL structure.
*/
#ifdef M_RCSID
#ifndef lint
static char rcsID[] = "$Id: tput.c 1.28 1995/04/12 09:28:05 ross Exp $";
#endif
#endif
#include <mks.h>
#include <curses.h>
#include <term.h>
#include <ctype.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern char *_cmdname;
/* Exit Status */
#define SUCCESS 0
#define NOT_DEFINED 1
#define USAGE 2
#define BAD_TERMINAL 3
#define NOT_VALID 4
#define ERROR 5
static int S_flag = 0;
static char *term_name;
static char dumb_term[] = "dumb";
static char usage_msg[] = m_textstr(4931, "\
Usage: tput [-W] [-Tterm] capname [parm1..parm9]\n\
tput [-W] [-Tterm] -S\n", "U");
STATREF void build_argv ANSI((int *ac, char ***av));
STATREF int do_tput ANSI((int _argc, char **_argv));
STATREF void init ANSI((void));
STATREF void reset ANSI((void));
STATREF int usage ANSI((void));
STATREF void err_msg ANSI((char *fmt, ...)); /* GENTEXT: err_msg */
STATREF void cat ANSI((char *_Fn));
/*f
* mainline for tput
*/
int
main(argc, argv)
int argc;
char **argv;
{
int opt;
int err_code;
setlocale(LC_ALL, "");
_cmdname = m_cmdname(*argv);
if ((term_name = getenv("TERM")) == NULL) {
term_name = dumb_term;
} else {
term_name = m_strdup(term_name);
}
/* Default uses the terminfo database without modification. */
use_env(0);
while ((opt = getopt(argc, argv, "ST:W")) != -1) {
switch (opt) {
case 'W':
/* Environment/window size are consulted and may
* alter the database entries for lines and columns.
*/
use_env(1);
break;
case 'S':
S_flag = 1;
break;
case 'T':
term_name = optarg;
break;
default:
return (usage());
}
}
argc -= optind;
argv += optind;
if ((S_flag ^ (argc <= 0)) == 1)
return (usage());
(void) setupterm(term_name, fileno(stdout), &err_code);
switch (err_code) {
case 1:
break;
case 0:
err_msg(m_textstr(202, "Unknown terminal \"%s\".\n", "E term"), term_name);
return (BAD_TERMINAL);
case -1:
err_msg(m_textstr(203, "No terminfo database.\n", "E"));
return (BAD_TERMINAL);
}
do {
if (S_flag) {
build_argv(&argc, &argv);
if (argc <= 0)
break;
}
err_code = do_tput(argc, argv);
} while (S_flag && err_code == SUCCESS);
return (err_code);
}
/*f
* Get an input line from stdin and then break it up into an argv array.
* If EOF is reached then S_flag is set to 0. Only the first 10 strings
* are of any interest. Any extra are ignored.
*/
STATIC void
build_argv(ac, av)
int *ac;
char ***av;
{
int i = 0;
char *p;
static char *v[10+1];
static char buf[LINE_MAX];
if ((*v = fgets(buf, LINE_MAX, stdin)) == NULL) {
/* End of file or input error */
S_flag = 0;
} else {
if ((p = strchr(buf, '\n')) != NULL)
*p = '\0';
for (p = buf; i < 10;) {
while (isspace(*(unsigned char*) p))
++p;
if (*p == '\0')
break;
v[i++] = p;
while (!isspace(*(unsigned char*) p) && *p != '\0')
++p;
if (*p == '\0')
break;
*p++ = '\0';
}
}
v[i] = NULL;
*ac = i;
*av = v;
}
/*f
*
*/
STATIC int
do_tput(_argc, _argv)
int _argc;
char **_argv;
{
int i;
long q[9];
const char *p;
char *end_num;
if (strcmp(*_argv, "init") == 0)
init();
else if (strcmp(*_argv, "reset") == 0)
reset();
else if (strcmp(*_argv, "longname") == 0)
(void) printf("%s\n", longname());
else if ((i = tigetflag(*_argv)) != -1)
return (!i);
else if ((i = tigetnum(*_argv)) != -2)
(void) printf("%d\n", i);
else if ((p = tigetstr(*_argv)) != (char*) -1) {
if (p == NULL)
return (NOT_DEFINED);
for (i = 0; i < 9; ++i) {
if (1 < _argc) {
--_argc;
q[i] = strtol(*++_argv, &end_num, 0);
if (*end_num != '\0') {
/* The parameter must be a string
* so we save the pointer instead.
*/
q[i] = (long) *_argv;
}
} else {
q[i] = 0L;
}
}
(void) putp(tparm(p, q[0], q[1], q[2], q[3],
q[4], q[5], q[6], q[7], q[8]
));
fflush(stdout);
} else {
err_msg(m_textstr(1864, "Unknown terminfo capability \"%s\".\n", "E action"), *_argv);
return (NOT_VALID);
}
return (SUCCESS);
}
/*f
*
*/
STATIC void
init()
{
if (init_prog != NULL)
(void) system(init_prog);
if (init_1string != NULL)
putp(init_1string);
if (init_2string != NULL)
putp(init_2string);
#if 0 /* currently not supported by our terminfo database */
if (clear_margins != NULL)
putp(clear_margins);
if (set_left_margin != NULL)
putp(set_left_margin);
if (set_right_margin != NULL)
putp(set_right_margin);
#endif
/* TODO: setting of tabs using clear_all_tabs & set_tab. */
if (init_file != NULL)
cat(init_file);
if (init_3string != NULL)
putp(init_3string);
}
/*f
*
*/
STATIC void
reset()
{
if (reset_1string != NULL)
putp(reset_1string);
if (reset_2string != NULL)
putp(reset_2string);
if (reset_file != NULL)
cat(reset_file);
if (reset_3string != NULL)
putp(reset_3string);
}
/*f
* usage message for tput
*/
STATIC int
usage()
{
(void) fprintf(stderr, m_strmsg(usage_msg));
return (USAGE);
}
/*f
* display error message
*/
STATIC void
err_msg VARARG1(char*, fmt)
{
va_list ap;
(void) fprintf(stderr, "%s: ", _cmdname);
va_start(ap, fmt);
(void) vfprintf(stderr, m_strmsg(fmt), ap);
va_end(ap);
}
/*
* Print a file via putp().
*/
STATIC void
cat(fn)
char *fn;
{
FILE *fp;
char buf[LINE_MAX+1];
if ((fp = fopen(fn, "rb")) == NULL)
return;
while (fgets(buf, LINE_MAX, fp) != NULL)
putp(buf);
(void) fclose(fp);
}