version 1.29, 2023/09/06 05:04:07 |
version 1.30, 2023/10/17 09:52:11 |
|
|
/* $OpenBSD$ */ |
/* $OpenBSD$ */ |
|
|
|
/**************************************************************************** |
|
* Copyright 2018-2022,2023 Thomas E. Dickey * |
|
* Copyright 1998-2016,2017 Free Software Foundation, Inc. * |
|
* * |
|
* Permission is hereby granted, free of charge, to any person obtaining a * |
|
* copy of this software and associated documentation files (the * |
|
* "Software"), to deal in the Software without restriction, including * |
|
* without limitation the rights to use, copy, modify, merge, publish, * |
|
* distribute, distribute with modifications, sublicense, and/or sell * |
|
* copies of the Software, and to permit persons to whom the Software is * |
|
* furnished to do so, subject to the following conditions: * |
|
* * |
|
* The above copyright notice and this permission notice shall be included * |
|
* in all copies or substantial portions of the Software. * |
|
* * |
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * |
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * |
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * |
|
* IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * |
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * |
|
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * |
|
* THE USE OR OTHER DEALINGS IN THE SOFTWARE. * |
|
* * |
|
* Except as contained in this notice, the name(s) of the above copyright * |
|
* holders shall not be used in advertising or otherwise to promote the * |
|
* sale, use or other dealings in this Software without prior written * |
|
* authorization. * |
|
****************************************************************************/ |
|
|
|
/**************************************************************************** |
|
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * |
|
* and: Eric S. Raymond <esr@snark.thyrsus.com> * |
|
* and: Thomas E. Dickey 1996-on * |
|
****************************************************************************/ |
|
|
/* |
/* |
* Copyright (c) 1999 Todd C. Miller <millert@openbsd.org> |
* tput.c -- shellscript access to terminal capabilities |
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* by Eric S. Raymond <esr@snark.thyrsus.com>, portions based on code from |
* purpose with or without fee is hereby granted, provided that the above |
* Ross Ridge's mytinfo package. |
* copyright notice and this permission notice appear in all copies. |
|
* |
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
*/ |
*/ |
/*- |
|
* Copyright (c) 1980, 1988, 1993 |
|
* The Regents of the University of California. All rights reserved. |
|
* |
|
* Redistribution and use in source and binary forms, with or without |
|
* modification, are permitted provided that the following conditions |
|
* are met: |
|
* 1. Redistributions of source code must retain the above copyright |
|
* notice, this list of conditions and the following disclaimer. |
|
* 2. Redistributions in binary form must reproduce the above copyright |
|
* notice, this list of conditions and the following disclaimer in the |
|
* documentation and/or other materials provided with the distribution. |
|
* 3. Neither the name of the University nor the names of its contributors |
|
* may be used to endorse or promote products derived from this software |
|
* without specific prior written permission. |
|
* |
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
* SUCH DAMAGE. |
|
*/ |
|
|
|
#include <sys/wait.h> |
#include <tparm_type.h> |
#include <ctype.h> |
#include <clear_cmd.h> |
#include <err.h> |
#include <reset_cmd.h> |
#include <curses.h> |
|
#include <term.h> |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <unistd.h> |
|
#include <errno.h> |
|
#include <limits.h> |
|
#include <string.h> |
|
|
|
#define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) |
#include <transform.h> |
|
#include <tty_settings.h> |
|
|
#define NUM_PARM 9 /* must match tic.h */ |
|
|
|
static void init(void); |
|
static char **process(char *, char *, char **); |
|
static void reset(void); |
|
static void set_margins(void); |
|
static void usage(void); |
|
|
|
extern char *__progname; |
#define PUTS(s) fputs(s, stdout) |
extern int _nc_tparm_analyze(const char *string, char *p_is_s[NUM_PARM], int *popcount); |
|
|
|
int |
const char *_nc_progname = "tput"; |
main(int argc, char *argv[]) |
|
{ |
|
int ch, exitval, n, Sflag; |
|
size_t len; |
|
char *p, *term, *str; |
|
char **oargv; |
|
|
|
if (pledge("stdio rpath wpath tty", NULL) == -1) |
static bool opt_v = FALSE; /* quiet, do not show warnings */ |
err(1, "pledge"); |
static bool opt_x = FALSE; /* clear scrollback if possible */ |
|
|
oargv = argv; |
static bool is_init = FALSE; |
term = NULL; |
static bool is_reset = FALSE; |
Sflag = exitval = 0; |
static bool is_clear = FALSE; |
while ((ch = getopt(argc, argv, "ST:")) != -1) |
|
switch(ch) { |
|
case 'T': |
|
term = optarg; |
|
break; |
|
case 'S': |
|
Sflag = 1; |
|
break; |
|
default: |
|
usage(); |
|
} |
|
argc -= optind; |
|
argv += optind; |
|
|
|
if (Sflag && argc > 0) |
static GCC_NORETURN void |
usage(); |
quit(int status, const char *fmt, ...) |
|
{ |
|
va_list argp; |
|
|
if (!term && !(term = getenv("TERM"))) |
va_start(argp, fmt); |
errx(2, "No value for $TERM and no -T specified"); |
fprintf(stderr, "%s: ", _nc_progname); |
|
vfprintf(stderr, fmt, argp); |
|
fprintf(stderr, "\n"); |
|
va_end(argp); |
|
ExitProgram(status); |
|
} |
|
|
/* |
static GCC_NORETURN void |
* NOTE: tgetent() will call setupterm() and set ospeed for us |
usage(const char *optstring) |
* (this is ncurses-specific behavior) |
{ |
*/ |
#define KEEP(s) s "\n" |
if (tgetent(NULL, term) != 1) |
static const char msg[] = |
errx(3, "Unknown terminal type `%s'", term); |
{ |
|
KEEP("") |
if (strcmp(__progname, "clear") == 0) { |
KEEP("Options:") |
if (Sflag) |
KEEP(" -S << read commands from standard input") |
usage(); |
KEEP(" -T TERM use this instead of $TERM") |
argv = oargv; |
KEEP(" -V print curses-version") |
*argv = __progname; |
KEEP(" -v verbose, show warnings") |
*(argv+1) = NULL; |
KEEP(" -x do not try to clear scrollback") |
|
KEEP("") |
|
KEEP("Commands:") |
|
KEEP(" clear clear the screen") |
|
KEEP(" init initialize the terminal") |
|
KEEP(" reset reinitialize the terminal") |
|
KEEP(" capname unlike clear/init/reset, print value for capability \"capname\"") |
|
}; |
|
#undef KEEP |
|
(void) fprintf(stderr, "Usage: %s [options] [command]\n", _nc_progname); |
|
if (optstring != NULL) { |
|
const char *s = msg; |
|
while (*s != '\0') { |
|
fputc(UChar(*s), stderr); |
|
if (!strncmp(s, " -", 3)) { |
|
if (strchr(optstring, s[3]) == NULL) |
|
s = strchr(s, '\n') + 1; |
|
} else if (!strncmp(s, "\n\nC", 3)) |
|
break; |
|
++s; |
} |
} |
if (Sflag) { |
} else { |
char **av; |
fputs(msg, stderr); |
|
} |
|
ExitProgram(ErrUsage); |
|
} |
|
|
/* Build new argv based on stdin */ |
static char * |
argc = n = 0; |
check_aliases(char *name, bool program) |
av = NULL; |
{ |
while ((str = fgetln(stdin, &len)) != NULL) { |
static char my_init[] = "init"; |
if (str[len-1] != '\n') |
static char my_reset[] = "reset"; |
errx(1, "premature EOF"); |
static char my_clear[] = "clear"; |
str[len-1] = '\0'; |
|
while ((p = strsep(&str, " \t")) != NULL) { |
|
/* grow av as needed */ |
|
if (argc + 1 >= n) { |
|
n += 64; |
|
av = reallocarray(av, n, |
|
sizeof(char *)); |
|
if (av == NULL) |
|
errx(1, "out of memory"); |
|
} |
|
if (*p != '\0' && |
|
(av[argc++] = strdup(p)) == NULL) |
|
errx(1, "out of memory"); |
|
} |
|
} |
|
if (argc > 0) { |
|
av[argc] = NULL; |
|
argv = av; |
|
} |
|
} |
|
while ((p = *argv++)) { |
|
switch (*p) { |
|
case 'i': |
|
if (!strcmp(p, "init")) { |
|
init(); |
|
continue; |
|
} |
|
break; |
|
case 'l': |
|
if (!strcmp(p, "longname")) { |
|
puts(longname()); |
|
continue; |
|
} |
|
break; |
|
case 'r': |
|
if (!strcmp(p, "reset")) { |
|
reset(); |
|
continue; |
|
} |
|
break; |
|
} |
|
|
|
/* First try as terminfo */ |
char *result = name; |
if ((str = tigetstr(p)) && str != (char *)-1) |
if ((is_init = same_program(name, program ? PROG_INIT : my_init))) |
argv = process(p, str, argv); |
result = my_init; |
else if ((n = tigetnum(p)) != -2) |
if ((is_reset = same_program(name, program ? PROG_RESET : my_reset))) |
(void)printf("%d\n", n); |
result = my_reset; |
else if ((n = tigetflag(p)) != -1) |
if ((is_clear = same_program(name, program ? PROG_CLEAR : my_clear))) |
exitval = !n; |
result = my_clear; |
/* Then fall back on termcap */ |
return result; |
else if ((str = tgetstr(p, NULL))) |
|
argv = process(p, str, argv); |
|
else if ((n = tgetnum(p)) != -1) |
|
(void)printf("%d\n", n); |
|
else if ((exitval = tgetflag(p)) != 0) |
|
exitval = !exitval; |
|
else { |
|
warnx("Unknown terminfo capability `%s'", p); |
|
exitval = 4; |
|
} |
|
} |
|
exit(exitval); |
|
} |
} |
|
|
static char ** |
static int |
process(char *cap, char *str, char **argv) |
exit_code(int token, int value) |
{ |
{ |
char *s, *nargv[NUM_PARM] = {0}; |
int result = 99; |
char *p_is_s[NUM_PARM]; |
|
int arg_need, i; |
|
|
|
/* Count how many values we need for this capability. */ |
switch (token) { |
i = _nc_tparm_analyze(str, p_is_s, &arg_need); |
case BOOLEAN: |
if (arg_need == 0) |
result = !value; /* TRUE=0, FALSE=1 */ |
arg_need = i; |
break; |
if (arg_need > NUM_PARM) |
case NUMBER: |
errx(2, "too many arguments (%d) for capability `%s'", |
result = 0; /* always zero */ |
arg_need, cap); |
break; |
|
case STRING: |
for (i = 0; i < arg_need; i++) { |
result = value; /* 0=normal, 1=missing */ |
const char *errstr; |
break; |
long l; |
} |
|
return result; |
|
} |
|
|
if (argv[i] == NULL) |
/* |
errx(2, "not enough arguments (%d) for capability `%s'", |
* Returns nonzero on error. |
arg_need, cap); |
*/ |
|
static int |
|
tput_cmd(int fd, TTY * settings, int argc, char **argv, int *used) |
|
{ |
|
NCURSES_CONST char *name; |
|
char *s; |
|
int status; |
|
#if !PURE_TERMINFO |
|
bool termcap = FALSE; |
|
#endif |
|
|
if (p_is_s[i] != 0) { |
name = check_aliases(argv[0], FALSE); |
nargv[i] = argv[i]; |
*used = 1; |
} else { |
if (is_reset || is_init) { |
/* convert ascii representation of numbers to longs */ |
TTY oldmode = *settings; |
l = strtonum(argv[i], LONG_MIN, LONG_MAX, &errstr); |
|
if (errstr != NULL) |
int terasechar = -1; /* new erase character */ |
errx(2, "capability `%s' is %s", cap, errstr); |
int intrchar = -1; /* new interrupt character */ |
nargv[i] = (char *)l; |
int tkillchar = -1; /* new kill character */ |
} |
|
|
if (is_reset) { |
|
reset_start(stdout, TRUE, FALSE); |
|
reset_tty_settings(fd, settings, FALSE); |
|
} else { |
|
reset_start(stdout, FALSE, TRUE); |
} |
} |
|
|
s = tparm(str, nargv[0], nargv[1], nargv[2], nargv[3], |
#if HAVE_SIZECHANGE |
nargv[4], nargv[5], nargv[6], nargv[7], nargv[8]); |
set_window_size(fd, &lines, &columns); |
putp(s); |
#else |
fflush(stdout); |
(void) fd; |
|
#endif |
|
set_control_chars(settings, terasechar, intrchar, tkillchar); |
|
set_conversions(settings); |
|
|
return (argv + arg_need); |
if (send_init_strings(fd, &oldmode)) { |
} |
reset_flush(); |
|
} |
|
|
static void |
update_tty_settings(&oldmode, settings); |
init(void) |
return 0; |
{ |
} |
FILE *ifile; |
|
size_t len; |
|
char *buf; |
|
int wstatus; |
|
pid_t pid; |
|
|
|
if (init_prog && !issetugid()) { |
if (strcmp(name, "longname") == 0) { |
switch (pid = vfork()) { |
PUTS(longname()); |
case -1: |
return 0; |
err(4, "vfork"); |
} |
break; |
#if !PURE_TERMINFO |
case 0: |
retry: |
/* child */ |
#endif |
execl(init_prog, init_prog, (char *)NULL); |
if (strcmp(name, "clear") == 0) { |
_exit(127); |
return (clear_cmd(opt_x) == ERR) ? ErrUsage : 0; |
break; |
} else if ((status = tigetflag(name)) != -1) { |
default: |
return exit_code(BOOLEAN, status); |
while (waitpid(pid, &wstatus, 0) == -1) { |
} else if ((status = tigetnum(name)) != CANCELLED_NUMERIC) { |
if (errno != EINTR) |
(void) printf("%d\n", status); |
break; |
return exit_code(NUMBER, 0); |
} |
} else if ((s = tigetstr(name)) == CANCELLED_STRING) { |
/* parent */ |
#if !PURE_TERMINFO |
break; |
if (!termcap) { |
|
const struct name_table_entry *np; |
|
|
|
termcap = TRUE; |
|
if ((np = _nc_find_entry(name, _nc_get_hash_table(termcap))) != 0) { |
|
switch (np->nte_type) { |
|
case BOOLEAN: |
|
name = boolnames[np->nte_index]; |
|
break; |
|
|
|
case NUMBER: |
|
name = numnames[np->nte_index]; |
|
break; |
|
|
|
case STRING: |
|
name = strnames[np->nte_index]; |
|
break; |
} |
} |
|
goto retry; |
|
} |
} |
} |
if (init_1string) |
#endif |
putp(init_1string); |
quit(ErrCapName, "unknown terminfo capability '%s'", name); |
if (init_2string) |
} else if (VALID_STRING(s)) { |
putp(init_2string); |
if (argc > 1) { |
set_margins(); |
int k; |
/* always use 8 space tabs */ |
int narg; |
if (init_tabs != 8 && clear_all_tabs && set_tab) { |
int analyzed; |
int i; |
int provided; |
|
int popcount; |
|
long numbers[1 + NUM_PARM]; |
|
char *strings[1 + NUM_PARM]; |
|
char *p_is_s[NUM_PARM]; |
|
TParams paramType; |
|
|
putp(clear_all_tabs); |
/* Nasty hack time. The tparm function needs to see numeric |
for (i = 0; i < (columns - 1) / 8; i++) { |
* parameters as numbers, not as pointers to their string |
if (parm_right_cursor) |
* representations |
putp(tparm(parm_right_cursor, 8)); |
*/ |
else |
|
fputs(" ", stdout); |
for (k = 1; (k < argc) && (k <= NUM_PARM); k++) { |
putp(set_tab); |
char *tmp = 0; |
|
strings[k] = argv[k]; |
|
numbers[k] = strtol(argv[k], &tmp, 0); |
|
if (tmp == 0 || *tmp != 0) |
|
numbers[k] = 0; |
|
} |
|
for (k = argc; k <= NUM_PARM; k++) { |
|
numbers[k] = 0; |
|
strings[k] = 0; |
|
} |
|
|
|
paramType = tparm_type(name); |
|
#if NCURSES_XNAMES |
|
/* |
|
* If the capability is an extended one, analyze the string. |
|
*/ |
|
if (paramType == Numbers) { |
|
struct name_table_entry const *entry_ptr; |
|
entry_ptr = _nc_find_type_entry(name, STRING, FALSE); |
|
if (entry_ptr == NULL) { |
|
paramType = Other; |
} |
} |
|
} |
|
#endif |
|
|
|
popcount = 0; |
|
_nc_reset_tparm(NULL); |
|
/* |
|
* Count the number of numeric parameters which are provided. |
|
*/ |
|
provided = 0; |
|
for (narg = 1; narg < argc; ++narg) { |
|
char *ending = NULL; |
|
long check = strtol(argv[narg], &ending, 10); |
|
if (check < 0 || ending == argv[narg] || *ending != '\0') |
|
break; |
|
provided = narg; |
|
} |
|
switch (paramType) { |
|
case Str: |
|
s = TPARM_1(s, strings[1]); |
|
analyzed = 1; |
|
if (provided == 0 && argc >= 1) |
|
provided++; |
|
break; |
|
case Str_Str: |
|
s = TPARM_2(s, strings[1], strings[2]); |
|
analyzed = 2; |
|
if (provided == 0 && argc >= 1) |
|
provided++; |
|
if (provided == 1 && argc >= 2) |
|
provided++; |
|
break; |
|
case Num_Str: |
|
s = TPARM_2(s, numbers[1], strings[2]); |
|
analyzed = 2; |
|
if (provided == 1 && argc >= 2) |
|
provided++; |
|
break; |
|
case Num_Str_Str: |
|
s = TPARM_3(s, numbers[1], strings[2], strings[3]); |
|
analyzed = 3; |
|
if (provided == 1 && argc >= 2) |
|
provided++; |
|
if (provided == 2 && argc >= 3) |
|
provided++; |
|
break; |
|
case Numbers: |
|
analyzed = _nc_tparm_analyze(NULL, s, p_is_s, &popcount); |
|
#define myParam(n) numbers[n] |
|
s = TIPARM_9(s, |
|
myParam(1), |
|
myParam(2), |
|
myParam(3), |
|
myParam(4), |
|
myParam(5), |
|
myParam(6), |
|
myParam(7), |
|
myParam(8), |
|
myParam(9)); |
|
#undef myParam |
|
break; |
|
case Other: |
|
/* FALLTHRU */ |
|
default: |
|
analyzed = _nc_tparm_analyze(NULL, s, p_is_s, &popcount); |
|
#define myParam(n) (p_is_s[n - 1] != 0 ? ((TPARM_ARG) strings[n]) : numbers[n]) |
|
s = TPARM_9(s, |
|
myParam(1), |
|
myParam(2), |
|
myParam(3), |
|
myParam(4), |
|
myParam(5), |
|
myParam(6), |
|
myParam(7), |
|
myParam(8), |
|
myParam(9)); |
|
#undef myParam |
|
break; |
|
} |
|
if (analyzed < popcount) { |
|
analyzed = popcount; |
|
} |
|
if (opt_v && (analyzed != provided)) { |
|
fprintf(stderr, "%s: %s parameters for \"%s\"\n", |
|
_nc_progname, |
|
(analyzed < provided ? "extra" : "missing"), |
|
argv[0]); |
|
} |
|
*used += provided; |
} |
} |
if (init_file && !issetugid() && (ifile = fopen(init_file, "r"))) { |
|
while ((buf = fgetln(ifile, &len)) != NULL) { |
/* use putp() in order to perform padding */ |
if (buf[len-1] != '\n') |
putp(s); |
errx(1, "premature EOF reading %s", init_file); |
return exit_code(STRING, 0); |
buf[len-1] = '\0'; |
} |
putp(buf); |
return exit_code(STRING, 1); |
} |
|
fclose(ifile); |
|
} |
|
if (init_3string) |
|
putp(init_3string); |
|
fflush(stdout); |
|
} |
} |
|
|
static void |
int |
reset(void) |
main(int argc, char **argv) |
{ |
{ |
FILE *rfile; |
char *term; |
size_t len; |
int errret; |
char *buf; |
bool cmdline = TRUE; |
|
int c; |
|
char buf[BUFSIZ]; |
|
int result = 0; |
|
int fd; |
|
int used; |
|
TTY old_settings; |
|
TTY tty_settings; |
|
bool is_alias; |
|
bool need_tty; |
|
|
if (reset_1string) |
if (pledge("stdio rpath wpath tty", NULL) == -1) { |
putp(reset_1string); |
perror("pledge"); |
if (reset_2string) |
exit(1); |
putp(reset_2string); |
} |
set_margins(); |
|
if (reset_file && !issetugid() && (rfile = fopen(reset_file, "r"))) { |
_nc_progname = check_aliases(_nc_rootname(argv[0]), TRUE); |
while ((buf = fgetln(rfile, &len)) != NULL) { |
is_alias = (is_clear || is_reset || is_init); |
if (buf[len-1] != '\n') |
|
errx(1, "premature EOF reading %s", reset_file); |
term = getenv("TERM"); |
buf[len-1] = '\0'; |
|
putp(buf); |
while ((c = getopt(argc, argv, is_alias ? "T:Vvx" : "ST:Vvx")) != -1) { |
} |
switch (c) { |
fclose(rfile); |
case 'S': |
|
cmdline = FALSE; |
|
break; |
|
case 'T': |
|
use_env(FALSE); |
|
use_tioctl(TRUE); |
|
term = optarg; |
|
break; |
|
case 'V': |
|
puts(curses_version()); |
|
ExitProgram(EXIT_SUCCESS); |
|
case 'v': /* verbose */ |
|
opt_v = TRUE; |
|
break; |
|
case 'x': /* do not try to clear scrollback */ |
|
opt_x = TRUE; |
|
break; |
|
default: |
|
usage(is_alias ? "TVx" : NULL); |
|
/* NOTREACHED */ |
} |
} |
if (reset_3string) |
} |
putp(reset_3string); |
|
fflush(stdout); |
|
} |
|
|
|
static void |
need_tty = ((is_reset || is_init) || |
set_margins(void) |
(optind < argc && |
{ |
(!strcmp(argv[optind], "reset") || |
|
!strcmp(argv[optind], "init")))); |
|
|
/* |
/* |
* Four possibilities: |
* Modify the argument list to omit the options we processed. |
* 1) we have set_lr_margin and can set things with one call |
*/ |
* 2) we have set_{left,right}_margin_parm, use two calls |
if (is_alias) { |
* 3) we have set_{left,right}_margin, set based on position |
if (optind-- < argc) { |
* 4) none of the above, leave things the way they are |
argc -= optind; |
*/ |
argv += optind; |
if (set_lr_margin) { |
} |
putp(tparm(set_lr_margin, 0, columns - 1)); |
argv[0] = strdup(_nc_progname); |
} else if (set_left_margin_parm && set_right_margin_parm) { |
} else { |
putp(tparm(set_left_margin_parm, 0)); |
argc -= optind; |
putp(tparm(set_right_margin_parm, columns - 1)); |
argv += optind; |
} else if (set_left_margin && set_right_margin && clear_margins) { |
} |
putp(clear_margins); |
|
|
|
/* go to column 0 and set the left margin */ |
if (term == 0 || *term == '\0') |
putp(carriage_return ? carriage_return : "\r"); |
quit(ErrUsage, "No value for $TERM and no -T specified"); |
putp(set_left_margin); |
|
|
|
/* go to last column and set the right margin */ |
fd = save_tty_settings(&tty_settings, need_tty); |
if (parm_right_cursor) |
old_settings = tty_settings; |
putp(tparm(parm_right_cursor, columns - 1)); |
|
else |
if (setupterm(term, fd, &errret) != OK && errret <= 0) |
printf("%*s", columns - 1, " "); |
quit(ErrTermType, "unknown terminal \"%s\"", term); |
putp(set_right_margin); |
|
putp(carriage_return ? carriage_return : "\r"); |
if (cmdline) { |
|
int code = 0; |
|
if ((argc <= 0) && !is_alias) |
|
usage(NULL); |
|
while (argc > 0) { |
|
tty_settings = old_settings; |
|
code = tput_cmd(fd, &tty_settings, argc, argv, &used); |
|
if (code != 0) |
|
break; |
|
argc -= used; |
|
argv += used; |
} |
} |
fflush(stdout); |
ExitProgram(code); |
} |
} |
|
|
static void |
while (fgets(buf, sizeof(buf), stdin) != 0) { |
usage(void) |
size_t need = strlen(buf); |
{ |
char **argvec = typeCalloc(char *, need + 1); |
|
char **argnow; |
|
int argnum = 0; |
|
char *cp; |
|
|
if (strcmp(__progname, "clear") == 0) |
if (argvec == NULL) { |
(void)fprintf(stderr, "usage: %s [-T term]\n", __progname); |
quit(ErrSystem(1), strerror(errno)); |
else |
} |
(void)fprintf(stderr, |
|
"usage: %s [-T term] attribute [attribute-arg ...] ...\n" |
/* split the buffer into tokens */ |
" %s [-T term] -S\n", __progname, __progname); |
for (cp = buf; *cp; cp++) { |
exit(1); |
if (isspace(UChar(*cp))) { |
|
*cp = '\0'; |
|
} else if (cp == buf || cp[-1] == '\0') { |
|
argvec[argnum++] = cp; |
|
if (argnum >= (int) need) |
|
break; |
|
} |
|
} |
|
|
|
argnow = argvec; |
|
while (argnum > 0) { |
|
int code; |
|
tty_settings = old_settings; |
|
code = tput_cmd(fd, &tty_settings, argnum, argnow, &used); |
|
if (code != 0) { |
|
if (result == 0) |
|
result = ErrSystem(0); /* will return value >4 */ |
|
++result; |
|
} |
|
argnum -= used; |
|
argnow += used; |
|
} |
|
free(argvec); |
|
} |
|
|
|
ExitProgram(result); |
} |
} |