watch: refactor code, add output_header() and run_command()
The main() was starting to be quite long with deep indents. Both signs of clean up being welcome change. FIXME: The comment also changes -g option to exit immediately, when screen contents change. This should be separated commit, e.g. the stuff is not ready to be merged. Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
parent
dbedc905fe
commit
85e0a23347
583
watch.c
583
watch.c
@ -62,6 +62,16 @@
|
|||||||
# define isprint(x) ( (x>=' '&&x<='~') || (x>=0xa0) )
|
# define isprint(x) ( (x>=' '&&x<='~') || (x>=0xa0) )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Boolean command line options */
|
||||||
|
static int flags;
|
||||||
|
#define WATCH_DIFF (1 << 1)
|
||||||
|
#define WATCH_CUMUL (1 << 2)
|
||||||
|
#define WATCH_EXEC (1 << 3)
|
||||||
|
#define WATCH_BEEP (1 << 4)
|
||||||
|
#define WATCH_COLOR (1 << 5)
|
||||||
|
#define WATCH_ERREXIT (1 << 6)
|
||||||
|
#define WATCH_CHGEXIT (1 << 7)
|
||||||
|
|
||||||
static int curses_started = 0;
|
static int curses_started = 0;
|
||||||
static long height = 24, width = 80;
|
static long height = 24, width = 80;
|
||||||
static int screen_size_changed = 0;
|
static int screen_size_changed = 0;
|
||||||
@ -285,15 +295,268 @@ wint_t my_getwc(FILE * s)
|
|||||||
}
|
}
|
||||||
#endif /* WITH_WATCH8BIT */
|
#endif /* WITH_WATCH8BIT */
|
||||||
|
|
||||||
|
void output_header(char *restrict command, double interval)
|
||||||
|
{
|
||||||
|
time_t t = time(NULL);
|
||||||
|
char *ts = ctime(&t);
|
||||||
|
int tsl = strlen(ts);
|
||||||
|
char *header;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* left justify interval and command, right justify time,
|
||||||
|
* clipping all to fit window width
|
||||||
|
*/
|
||||||
|
int hlen = asprintf(&header, _("Every %.1fs: "), interval);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the rules:
|
||||||
|
* width < tsl : print nothing
|
||||||
|
* width < tsl + hlen + 1: print ts
|
||||||
|
* width = tsl + hlen + 1: print header, ts
|
||||||
|
* width < tsl + hlen + 4: print header, ..., ts
|
||||||
|
* width < tsl + hlen + wcommand_columns: print header,
|
||||||
|
* truncated wcommand, ..., ts
|
||||||
|
* width > "": print header, wcomand, ts
|
||||||
|
* this is slightly different from how it used to be
|
||||||
|
*/
|
||||||
|
if (width < tsl) {
|
||||||
|
free(header);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (tsl + hlen + 1 <= width) {
|
||||||
|
mvaddstr(0, 0, header);
|
||||||
|
if (tsl + hlen + 2 <= width) {
|
||||||
|
if (width < tsl + hlen + 4) {
|
||||||
|
mvaddstr(0, width - tsl - 4, "... ");
|
||||||
|
} else {
|
||||||
|
#ifdef WITH_WATCH8BIT
|
||||||
|
if (width < tsl + hlen + wcommand_columns) {
|
||||||
|
/* print truncated */
|
||||||
|
int available = width - tsl - hlen;
|
||||||
|
int in_use = wcommand_columns;
|
||||||
|
int wcomm_len = wcommand_characters;
|
||||||
|
while (available - 4 < in_use) {
|
||||||
|
wcomm_len--;
|
||||||
|
in_use = wcswidth(wcommand, wcomm_len);
|
||||||
|
}
|
||||||
|
mvaddnwstr(0, hlen, wcommand, wcomm_len);
|
||||||
|
mvaddstr(0, width - tsl - 4, "... ");
|
||||||
|
} else {
|
||||||
|
mvaddwstr(0, hlen, wcommand);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
mvaddnstr(0, hlen, command, width - tsl - hlen);
|
||||||
|
#endif /* WITH_WATCH8BIT */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mvaddstr(0, width - tsl + 1, ts);
|
||||||
|
free(header);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int run_command(char *restrict command, char **restrict command_argv)
|
||||||
|
{
|
||||||
|
FILE *p;
|
||||||
|
int x, y;
|
||||||
|
int oldeolseen = 1;
|
||||||
|
int pipefd[2];
|
||||||
|
pid_t child;
|
||||||
|
int exit_early = 0;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
/* allocate pipes */
|
||||||
|
if (pipe(pipefd) < 0)
|
||||||
|
xerr(7, _("unable to create IPC pipes"));
|
||||||
|
|
||||||
|
/* flush stdout and stderr, since we're about to do fd stuff */
|
||||||
|
fflush(stdout);
|
||||||
|
fflush(stderr);
|
||||||
|
|
||||||
|
/* fork to prepare to run command */
|
||||||
|
child = fork();
|
||||||
|
|
||||||
|
if (child < 0) { /* fork error */
|
||||||
|
xerr(2, _("unable to fork process"));
|
||||||
|
} else if (child == 0) { /* in child */
|
||||||
|
close(pipefd[0]); /* child doesn't need read side of pipe */
|
||||||
|
close(1); /* prepare to replace stdout with pipe */
|
||||||
|
if (dup2(pipefd[1], 1) < 0) { /* replace stdout with write side of pipe */
|
||||||
|
xerr(3, _("dup2 failed"));
|
||||||
|
}
|
||||||
|
dup2(1, 2); /* stderr should default to stdout */
|
||||||
|
|
||||||
|
if (flags & WATCH_EXEC) { /* pass command to exec instead of system */
|
||||||
|
if (execvp(command_argv[0], command_argv) == -1) {
|
||||||
|
xerr(4, _("unable to execute '%s'"),
|
||||||
|
command_argv[0]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
status = system(command); /* watch manpage promises sh quoting */
|
||||||
|
/* propagate command exit status as child exit status */
|
||||||
|
if (!WIFEXITED(status)) { /* child exits nonzero if command does */
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
} else {
|
||||||
|
exit(WEXITSTATUS(status));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* otherwise, we're in parent */
|
||||||
|
close(pipefd[1]); /* close write side of pipe */
|
||||||
|
if ((p = fdopen(pipefd[0], "r")) == NULL)
|
||||||
|
xerr(5, _("fdopen"));
|
||||||
|
|
||||||
|
for (y = show_title; y < height; y++) {
|
||||||
|
int eolseen = 0, tabpending = 0;
|
||||||
|
#ifdef WITH_WATCH8BIT
|
||||||
|
wint_t carry = WEOF;
|
||||||
|
#endif
|
||||||
|
for (x = 0; x < width; x++) {
|
||||||
|
#ifdef WITH_WATCH8BIT
|
||||||
|
wint_t c = ' ';
|
||||||
|
#else
|
||||||
|
int c = ' ';
|
||||||
|
#endif
|
||||||
|
int attr = 0;
|
||||||
|
|
||||||
|
if (!eolseen) {
|
||||||
|
/* if there is a tab pending, just
|
||||||
|
* spit spaces until the next stop
|
||||||
|
* instead of reading characters */
|
||||||
|
if (!tabpending)
|
||||||
|
#ifdef WITH_WATCH8BIT
|
||||||
|
do {
|
||||||
|
if (carry == WEOF) {
|
||||||
|
c = my_getwc(p);
|
||||||
|
} else {
|
||||||
|
c = carry;
|
||||||
|
carry = WEOF;
|
||||||
|
}
|
||||||
|
} while (c != WEOF && !isprint(c)
|
||||||
|
&& c < 12
|
||||||
|
&& wcwidth(c) == 0
|
||||||
|
&& c != L'\n'
|
||||||
|
&& c != L'\t'
|
||||||
|
&& (c != L'\033'
|
||||||
|
|| !(flags & WATCH_COLOR)));
|
||||||
|
#else
|
||||||
|
do
|
||||||
|
c = getc(p);
|
||||||
|
while (c != EOF && !isprint(c)
|
||||||
|
&& c != '\n'
|
||||||
|
&& c != '\t'
|
||||||
|
&& (c != L'\033'
|
||||||
|
|| !(flags & WATCH_COLOR)));
|
||||||
|
#endif
|
||||||
|
if (c == L'\033' && (flags & WATCH_COLOR)) {
|
||||||
|
x--;
|
||||||
|
process_ansi(p);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c == L'\n')
|
||||||
|
if (!oldeolseen && x == 0) {
|
||||||
|
x = -1;
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
eolseen = 1;
|
||||||
|
else if (c == L'\t')
|
||||||
|
tabpending = 1;
|
||||||
|
#ifdef WITH_WATCH8BIT
|
||||||
|
if (x == width - 1 && wcwidth(c) == 2) {
|
||||||
|
y++;
|
||||||
|
x = -1; /* process this double-width */
|
||||||
|
carry = c; /* character on the next line */
|
||||||
|
continue; /* because it won't fit here */
|
||||||
|
}
|
||||||
|
if (c == WEOF || c == L'\n' || c == L'\t')
|
||||||
|
c = L' ';
|
||||||
|
#else
|
||||||
|
if (c == EOF || c == '\n' || c == '\t')
|
||||||
|
c = ' ';
|
||||||
|
#endif
|
||||||
|
if (tabpending && (((x + 1) % 8) == 0))
|
||||||
|
tabpending = 0;
|
||||||
|
}
|
||||||
|
move(y, x);
|
||||||
|
if (!first_screen && !exit_early && (flags & WATCH_CHGEXIT)) {
|
||||||
|
#ifdef WITH_WATCH8BIT
|
||||||
|
cchar_t oldc;
|
||||||
|
in_wch(&oldc);
|
||||||
|
exit_early = (wchar_t) c != oldc.chars[0];
|
||||||
|
#else
|
||||||
|
chtype oldch = inch();
|
||||||
|
unsigned char oldc = oldch & A_CHARTEXT;
|
||||||
|
exit_early = (unsigned char)c != oldc;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (flags & WATCH_DIFF) {
|
||||||
|
#ifdef WITH_WATCH8BIT
|
||||||
|
cchar_t oldc;
|
||||||
|
in_wch(&oldc);
|
||||||
|
attr = !first_screen
|
||||||
|
&& ((wchar_t) c != oldc.chars[0]
|
||||||
|
||
|
||||||
|
((flags & WATCH_CUMUL)
|
||||||
|
&& (oldc.attr & A_ATTRIBUTES)));
|
||||||
|
#else
|
||||||
|
chtype oldch = inch();
|
||||||
|
unsigned char oldc = oldch & A_CHARTEXT;
|
||||||
|
attr = !first_screen
|
||||||
|
&& ((unsigned char)c != oldc
|
||||||
|
||
|
||||||
|
((flags & WATCH_CUMUL)
|
||||||
|
&& (oldch & A_ATTRIBUTES)));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (attr)
|
||||||
|
standout();
|
||||||
|
#ifdef WITH_WATCH8BIT
|
||||||
|
addnwstr((wchar_t *) & c, 1);
|
||||||
|
#else
|
||||||
|
addch(c);
|
||||||
|
#endif
|
||||||
|
if (attr)
|
||||||
|
standend();
|
||||||
|
#ifdef WITH_WATCH8BIT
|
||||||
|
if (wcwidth(c) == 0) {
|
||||||
|
x--;
|
||||||
|
}
|
||||||
|
if (wcwidth(c) == 2) {
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
oldeolseen = eolseen;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(p);
|
||||||
|
|
||||||
|
/* harvest child process and get status, propagated from command */
|
||||||
|
if (waitpid(child, &status, 0) < 0)
|
||||||
|
xerr(8, _("waitpid"));
|
||||||
|
|
||||||
|
/* if child process exited in error, beep if option_beep is set */
|
||||||
|
if ((!WIFEXITED(status) || WEXITSTATUS(status))) {
|
||||||
|
if (flags & WATCH_BEEP)
|
||||||
|
beep();
|
||||||
|
if (flags & WATCH_ERREXIT) {
|
||||||
|
mvaddstr(height - 1, 0,
|
||||||
|
_("command exit with a non-zero status, press a key to exit"));
|
||||||
|
refresh();
|
||||||
|
fgetc(stdin);
|
||||||
|
endwin();
|
||||||
|
exit(8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
first_screen = 0;
|
||||||
|
refresh();
|
||||||
|
return exit_early;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int optc;
|
int optc;
|
||||||
int option_differences = 0,
|
|
||||||
option_differences_cumulative = 0,
|
|
||||||
option_exec = 0,
|
|
||||||
option_beep = 0,
|
|
||||||
option_color = 0,
|
|
||||||
option_errexit = 0, option_chgexit = 0;
|
|
||||||
double interval = 2;
|
double interval = 2;
|
||||||
char *command;
|
char *command;
|
||||||
char **command_argv;
|
char **command_argv;
|
||||||
@ -306,11 +569,6 @@ int main(int argc, char *argv[])
|
|||||||
int wcommand_characters = 0; /* not including final \0 */
|
int wcommand_characters = 0; /* not including final \0 */
|
||||||
#endif /* WITH_WATCH8BIT */
|
#endif /* WITH_WATCH8BIT */
|
||||||
|
|
||||||
int pipefd[2];
|
|
||||||
int status;
|
|
||||||
int exit_early = 0;
|
|
||||||
pid_t child;
|
|
||||||
|
|
||||||
static struct option longopts[] = {
|
static struct option longopts[] = {
|
||||||
{"color", no_argument, 0, 'c'},
|
{"color", no_argument, 0, 'c'},
|
||||||
{"differences", optional_argument, 0, 'd'},
|
{"differences", optional_argument, 0, 'd'},
|
||||||
@ -336,27 +594,27 @@ int main(int argc, char *argv[])
|
|||||||
!= EOF) {
|
!= EOF) {
|
||||||
switch (optc) {
|
switch (optc) {
|
||||||
case 'b':
|
case 'b':
|
||||||
option_beep = 1;
|
flags |= WATCH_BEEP;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
option_color = 1;
|
flags |= WATCH_COLOR;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
option_differences = 1;
|
flags |= WATCH_DIFF;
|
||||||
if (optarg)
|
if (optarg)
|
||||||
option_differences_cumulative = 1;
|
flags |= WATCH_CUMUL;
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
option_errexit = 1;
|
flags |= WATCH_ERREXIT;
|
||||||
break;
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
option_chgexit = 1;
|
flags |= WATCH_CHGEXIT;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
show_title = 0;
|
show_title = 0;
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
option_exec = 1;
|
flags |= WATCH_EXEC;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
interval = strtod_or_err(optarg, _("failed to parse argument"));
|
interval = strtod_or_err(optarg, _("failed to parse argument"));
|
||||||
@ -431,13 +689,14 @@ int main(int argc, char *argv[])
|
|||||||
/* Set up tty for curses use. */
|
/* Set up tty for curses use. */
|
||||||
curses_started = 1;
|
curses_started = 1;
|
||||||
initscr();
|
initscr();
|
||||||
if (option_color) {
|
if (flags & WATCH_COLOR) {
|
||||||
if (has_colors()) {
|
if (has_colors()) {
|
||||||
start_color();
|
start_color();
|
||||||
use_default_colors();
|
use_default_colors();
|
||||||
init_ansi_colors();
|
init_ansi_colors();
|
||||||
} else
|
} else {
|
||||||
option_color = 0;
|
flags |= WATCH_COLOR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
nonl();
|
nonl();
|
||||||
noecho();
|
noecho();
|
||||||
@ -446,15 +705,7 @@ int main(int argc, char *argv[])
|
|||||||
if (precise_timekeeping)
|
if (precise_timekeeping)
|
||||||
next_loop = get_time_usec();
|
next_loop = get_time_usec();
|
||||||
|
|
||||||
do {
|
while (1) {
|
||||||
time_t t = time(NULL);
|
|
||||||
char *ts = ctime(&t);
|
|
||||||
int tsl = strlen(ts);
|
|
||||||
char *header;
|
|
||||||
FILE *p;
|
|
||||||
int x, y;
|
|
||||||
int oldeolseen = 1;
|
|
||||||
|
|
||||||
if (screen_size_changed) {
|
if (screen_size_changed) {
|
||||||
get_terminal_size();
|
get_terminal_size();
|
||||||
resizeterm(height, width);
|
resizeterm(height, width);
|
||||||
@ -464,272 +715,11 @@ int main(int argc, char *argv[])
|
|||||||
first_screen = 1;
|
first_screen = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_title) {
|
if (show_title)
|
||||||
/*
|
output_header(command, interval);
|
||||||
* left justify interval and command, right
|
|
||||||
* justify time, clipping all to fit window
|
|
||||||
* width
|
|
||||||
*/
|
|
||||||
int hlen = asprintf(&header, _("Every %.1fs: "), interval);
|
|
||||||
|
|
||||||
/*
|
if (run_command(command, command_argv))
|
||||||
* the rules:
|
break;
|
||||||
* width < tsl : print nothing
|
|
||||||
* width < tsl + hlen + 1: print ts
|
|
||||||
* width = tsl + hlen + 1: print header, ts
|
|
||||||
* width < tsl + hlen + 4: print header, ..., ts
|
|
||||||
* width < tsl + hlen + wcommand_columns: print
|
|
||||||
* header, truncated wcommand,
|
|
||||||
* ..., ts
|
|
||||||
* width > "": print header, wcomand, ts
|
|
||||||
* this is slightly different from how it used to be
|
|
||||||
*/
|
|
||||||
if (width >= tsl) {
|
|
||||||
if (width >= tsl + hlen + 1) {
|
|
||||||
mvaddstr(0, 0, header);
|
|
||||||
if (width >= tsl + hlen + 2) {
|
|
||||||
if (width < tsl + hlen + 4) {
|
|
||||||
mvaddstr(0,
|
|
||||||
width - tsl -
|
|
||||||
4, "... ");
|
|
||||||
} else {
|
|
||||||
#ifdef WITH_WATCH8BIT
|
|
||||||
if (width <
|
|
||||||
tsl + hlen +
|
|
||||||
wcommand_columns) {
|
|
||||||
/* print truncated */
|
|
||||||
int avail_columns = width - tsl - hlen;
|
|
||||||
int using_columns = wcommand_columns;
|
|
||||||
int using_characters = wcommand_characters;
|
|
||||||
while (using_columns > avail_columns - 4) {
|
|
||||||
using_characters--;
|
|
||||||
using_columns
|
|
||||||
=
|
|
||||||
wcswidth
|
|
||||||
(wcommand,
|
|
||||||
using_characters);
|
|
||||||
}
|
|
||||||
mvaddnwstr(0,
|
|
||||||
hlen,
|
|
||||||
wcommand,
|
|
||||||
using_characters);
|
|
||||||
mvaddstr(0,
|
|
||||||
width -
|
|
||||||
tsl -
|
|
||||||
4,
|
|
||||||
"... ");
|
|
||||||
} else {
|
|
||||||
mvaddwstr(0,
|
|
||||||
hlen,
|
|
||||||
wcommand);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
mvaddnstr(0, hlen,
|
|
||||||
command,
|
|
||||||
width - tsl -
|
|
||||||
hlen);
|
|
||||||
#endif /* WITH_WATCH8BIT */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mvaddstr(0, width - tsl + 1, ts);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(header);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate pipes */
|
|
||||||
if (pipe(pipefd) < 0)
|
|
||||||
xerr(7, _("unable to create IPC pipes"));
|
|
||||||
|
|
||||||
/* flush stdout and stderr, since we're about to do fd stuff */
|
|
||||||
fflush(stdout);
|
|
||||||
fflush(stderr);
|
|
||||||
|
|
||||||
/* fork to prepare to run command */
|
|
||||||
child = fork();
|
|
||||||
|
|
||||||
if (child < 0) { /* fork error */
|
|
||||||
xerr(2, _("unable to fork process"));
|
|
||||||
} else if (child == 0) { /* in child */
|
|
||||||
close(pipefd[0]); /* child doesn't need read side of pipe */
|
|
||||||
close(1); /* prepare to replace stdout with pipe */
|
|
||||||
if (dup2(pipefd[1], 1) < 0) { /* replace stdout with write side of pipe */
|
|
||||||
xerr(3, _("dup2 failed"));
|
|
||||||
}
|
|
||||||
dup2(1, 2); /* stderr should default to stdout */
|
|
||||||
|
|
||||||
if (option_exec) { /* pass command to exec instead of system */
|
|
||||||
if (execvp(command_argv[0], command_argv) == -1) {
|
|
||||||
xerr(4, _("unable to execute '%s'"), command_argv[0]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
status = system(command); /* watch manpage promises sh quoting */
|
|
||||||
|
|
||||||
/* propagate command exit status as child exit status */
|
|
||||||
if (!WIFEXITED(status)) { /* child exits nonzero if command does */
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
} else {
|
|
||||||
exit(WEXITSTATUS(status));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* otherwise, we're in parent */
|
|
||||||
close(pipefd[1]); /* close write side of pipe */
|
|
||||||
if ((p = fdopen(pipefd[0], "r")) == NULL)
|
|
||||||
xerr(5, _("fdopen"));
|
|
||||||
|
|
||||||
for (y = show_title; y < height; y++) {
|
|
||||||
int eolseen = 0, tabpending = 0;
|
|
||||||
#ifdef WITH_WATCH8BIT
|
|
||||||
wint_t carry = WEOF;
|
|
||||||
#endif /* WITH_WATCH8BIT */
|
|
||||||
for (x = 0; x < width; x++) {
|
|
||||||
#ifdef WITH_WATCH8BIT
|
|
||||||
wint_t c = ' ';
|
|
||||||
#else
|
|
||||||
int c = ' ';
|
|
||||||
#endif /* WITH_WATCH8BIT */
|
|
||||||
int attr = 0;
|
|
||||||
|
|
||||||
if (!eolseen) {
|
|
||||||
/* if there is a tab pending, just
|
|
||||||
* spit spaces until the next stop
|
|
||||||
* instead of reading characters */
|
|
||||||
if (!tabpending)
|
|
||||||
#ifdef WITH_WATCH8BIT
|
|
||||||
do {
|
|
||||||
if (carry == WEOF) {
|
|
||||||
c = my_getwc(p);
|
|
||||||
} else {
|
|
||||||
c = carry;
|
|
||||||
carry = WEOF;
|
|
||||||
}
|
|
||||||
} while (c != WEOF
|
|
||||||
&& !isprint(c)
|
|
||||||
&& c < 12
|
|
||||||
&& wcwidth(c) == 0
|
|
||||||
&& c != L'\n'
|
|
||||||
&& c != L'\t'
|
|
||||||
&& (c != L'\033'
|
|
||||||
|| option_color !=
|
|
||||||
1));
|
|
||||||
#else
|
|
||||||
do
|
|
||||||
c = getc(p);
|
|
||||||
while (c != EOF && !isprint(c)
|
|
||||||
&& c != '\n'
|
|
||||||
&& c != '\t'
|
|
||||||
&& (c != L'\033'
|
|
||||||
|| option_color !=
|
|
||||||
1));
|
|
||||||
#endif /* WITH_WATCH8BIT */
|
|
||||||
if (c == L'\033' && option_color == 1) {
|
|
||||||
x--;
|
|
||||||
process_ansi(p);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c == L'\n')
|
|
||||||
if (!oldeolseen && x == 0) {
|
|
||||||
x = -1;
|
|
||||||
continue;
|
|
||||||
} else
|
|
||||||
eolseen = 1;
|
|
||||||
else if (c == L'\t')
|
|
||||||
tabpending = 1;
|
|
||||||
#ifdef WITH_WATCH8BIT
|
|
||||||
if (x == width - 1 && wcwidth(c) == 2) {
|
|
||||||
y++;
|
|
||||||
x = -1; /* process this double-width */
|
|
||||||
carry = c; /* character on the next line */
|
|
||||||
continue; /* because it won't fit here */
|
|
||||||
}
|
|
||||||
if (c == WEOF || c == L'\n'
|
|
||||||
|| c == L'\t')
|
|
||||||
c = L' ';
|
|
||||||
#else
|
|
||||||
if (c == EOF || c == '\n' || c == '\t')
|
|
||||||
c = ' ';
|
|
||||||
#endif /* WITH_WATCH8BIT */
|
|
||||||
if (tabpending && (((x + 1) % 8) == 0))
|
|
||||||
tabpending = 0;
|
|
||||||
}
|
|
||||||
move(y, x);
|
|
||||||
if (!first_screen && !exit_early && option_chgexit) {
|
|
||||||
#ifdef WITH_WATCH8BIT
|
|
||||||
cchar_t oldc;
|
|
||||||
in_wch(&oldc);
|
|
||||||
exit_early = (wchar_t) c != oldc.chars[0];
|
|
||||||
#else
|
|
||||||
chtype oldch = inch();
|
|
||||||
unsigned char oldc = oldch & A_CHARTEXT;
|
|
||||||
exit_early = (unsigned char) c != oldc;
|
|
||||||
#endif /* WITH_WATCH8BIT */
|
|
||||||
}
|
|
||||||
if (option_differences) {
|
|
||||||
#ifdef WITH_WATCH8BIT
|
|
||||||
cchar_t oldc;
|
|
||||||
in_wch(&oldc);
|
|
||||||
attr = !first_screen
|
|
||||||
&& ((wchar_t) c != oldc.chars[0]
|
|
||||||
||
|
|
||||||
(option_differences_cumulative
|
|
||||||
&& (oldc.
|
|
||||||
attr & A_ATTRIBUTES)));
|
|
||||||
#else
|
|
||||||
chtype oldch = inch();
|
|
||||||
unsigned char oldc = oldch & A_CHARTEXT;
|
|
||||||
attr = !first_screen
|
|
||||||
&& ((unsigned char)c != oldc
|
|
||||||
||
|
|
||||||
(option_differences_cumulative
|
|
||||||
&& (oldch & A_ATTRIBUTES)));
|
|
||||||
#endif /* WITH_WATCH8BIT */
|
|
||||||
}
|
|
||||||
if (attr)
|
|
||||||
standout();
|
|
||||||
#ifdef WITH_WATCH8BIT
|
|
||||||
addnwstr((wchar_t *) & c, 1);
|
|
||||||
#else
|
|
||||||
addch(c);
|
|
||||||
#endif /* WITH_WATCH8BIT */
|
|
||||||
if (attr)
|
|
||||||
standend();
|
|
||||||
#ifdef WITH_WATCH8BIT
|
|
||||||
if (wcwidth(c) == 0) {
|
|
||||||
x--;
|
|
||||||
}
|
|
||||||
if (wcwidth(c) == 2) {
|
|
||||||
x++;
|
|
||||||
}
|
|
||||||
#endif /* WITH_WATCH8BIT */
|
|
||||||
}
|
|
||||||
oldeolseen = eolseen;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(p);
|
|
||||||
|
|
||||||
/* harvest child process and get status, propagated from command */
|
|
||||||
if (waitpid(child, &status, 0) < 0)
|
|
||||||
xerr(8, _("waitpid"));
|
|
||||||
|
|
||||||
/* if child process exited in error, beep if option_beep is set */
|
|
||||||
if ((!WIFEXITED(status) || WEXITSTATUS(status))) {
|
|
||||||
if (option_beep)
|
|
||||||
beep();
|
|
||||||
if (option_errexit) {
|
|
||||||
mvaddstr(height - 1, 0,
|
|
||||||
_("command exit with a non-zero status, press a key to exit"));
|
|
||||||
refresh();
|
|
||||||
fgetc(stdin);
|
|
||||||
endwin();
|
|
||||||
exit(8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
first_screen = 0;
|
|
||||||
refresh();
|
|
||||||
if (precise_timekeeping) {
|
if (precise_timekeeping) {
|
||||||
watch_usec_t cur_time = get_time_usec();
|
watch_usec_t cur_time = get_time_usec();
|
||||||
next_loop += USECS_PER_SEC * interval;
|
next_loop += USECS_PER_SEC * interval;
|
||||||
@ -737,9 +727,8 @@ int main(int argc, char *argv[])
|
|||||||
usleep(next_loop - cur_time);
|
usleep(next_loop - cur_time);
|
||||||
} else
|
} else
|
||||||
usleep(interval * 1000000);
|
usleep(interval * 1000000);
|
||||||
} while (!exit_early);
|
}
|
||||||
|
|
||||||
endwin();
|
endwin();
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user