]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
more: add display_file() to show files and stdin
authorSami Kerola <kerolasa@iki.fi>
Sat, 28 Mar 2020 07:50:43 +0000 (07:50 +0000)
committerSami Kerola <kerolasa@iki.fi>
Sat, 28 Mar 2020 07:55:59 +0000 (07:55 +0000)
Earlier main() inline code implemented input files and stdin displaying
separately.  With small restructuring this code can be shared.

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
text-utils/more.c

index a2ab577a06abd2ecb723cbf664bbd8fa1b2180f7..cdc0cc2568b42ea2606f71c72be7022e5a18e772 100644 (file)
@@ -167,6 +167,7 @@ struct more_control {
                bad_stdout:1,           /* true if overwriting does not turn off standout */
                catch_suspend:1,        /* we should catch the SIGTSTP signal */
                clear_line_ends:1,      /* do not scroll, paint each screen from the top */
+               clear_first:1,          /* is first character in file \f */
                dumb_tty:1,             /* is terminal type known */
                eat_newline:1,          /* is newline ignored after 80 cols */
                enable_underlining:1,   /* underline as best we can */
@@ -176,13 +177,16 @@ struct more_control {
                fold_long_lines:1,      /* fold long lines */
                hard_tabs:1,            /* print spaces instead of '\t' */
                hard_tty:1,             /* is this hard copy terminal (a printer or such) */
+               jump_at_start:1,        /* jump to line N defined at start up */
                is_paused:1,            /* is output paused */
                no_quit_dialog:1,       /* suppress quit dialog */
                no_scroll:1,            /* do not scroll, clear the screen and then display text */
                no_tty_in:1,            /* is input in interactive mode */
                no_tty_out:1,           /* is output in interactive mode */
+               print_banner:1,         /* print file name banner */
                report_errors:1,        /* is an error reported */
                run_previous_command:1, /* run previous key command */
+               search_at_start:1,      /* search pattern defined at start up */
                search_called:1,        /* previous more command was a search */
                squeeze_spaces:1,       /* suppress white space */
                stdout_glitch:1,        /* terminal has standout mode glitch */
@@ -332,7 +336,7 @@ static int check_magic(FILE *f, char *fs)
 
 /* Check whether the file named by fs is an ASCII file which the user may
  * access.  If it is, return the opened file.  Otherwise return NULL. */
-static void checkf(struct more_control *ctl, char *fs, int *clearfirst)
+static void checkf(struct more_control *ctl, char *fs)
 {
        struct stat st;
        int c;
@@ -364,7 +368,7 @@ static void checkf(struct more_control *ctl, char *fs, int *clearfirst)
        }
        fcntl(fileno(ctl->current_file), F_SETFD, FD_CLOEXEC);
        c = more_getc(ctl);
-       *clearfirst = (c == '\f');
+       ctl->clear_first = (c == '\f');
        more_ungetc(ctl, c);
        if ((ctl->file_size = st.st_size) == 0)
                ctl->file_size = LONG_MAX;
@@ -1794,6 +1798,64 @@ static void copy_file(FILE *f)
                fwrite(&buf, sizeof(char), sz, stdout);
 }
 
+
+static void display_file(struct more_control *ctl, char *initbuf, int left)
+{
+       if (!ctl->current_file)
+               return;
+       ctl->context.line_num = ctl->context.row_num = 0;
+       ctl->current_line = 0;
+       if (ctl->first_file) {
+               ctl->first_file = 0;
+               if (ctl->search_at_start) {
+                       free(ctl->previous_search);
+                       ctl->previous_search = xstrdup(initbuf);
+                       search(ctl, initbuf, 1);
+                       if (ctl->no_scroll)
+                               left--;
+               } else if (ctl->jump_at_start)
+                       skip_lines(ctl, ctl->search_at_start);
+       } else if (ctl->argv_position < ctl->num_files && !ctl->no_tty_out)
+               left =
+                   more_key_command(ctl, ctl->file_names[ctl->argv_position]);
+       if (left != 0) {
+               if ((ctl->no_scroll || ctl->clear_first)
+                   && (ctl->file_size != LONG_MAX)) {
+                       if (ctl->clear_line_ends)
+                               putp(ctl->go_home);
+                       else
+                               more_clear_screen(ctl);
+               }
+               if (ctl->print_banner) {
+                       if (ctl->bad_stdout)
+                               erase_prompt(ctl, 0);
+                       if (ctl->clear_line_ends)
+                               putp(ctl->erase_line);
+                       fputs("::::::::::::::", stdout);
+                       if (ctl->prompt_len > 14)
+                               erase_prompt(ctl, 14);
+                       putchar('\n');
+                       if (ctl->clear_line_ends)
+                               putp(ctl->erase_line);
+                       puts(ctl->file_names[ctl->argv_position]);
+                       if (ctl->clear_line_ends)
+                               putp(ctl->erase_line);
+                       fputs("::::::::::::::\n", stdout);
+                       if (left > ctl->lines_per_page - 4)
+                               left = ctl->lines_per_page - 4;
+               }
+               if (ctl->no_tty_out)
+                       copy_file(ctl->current_file);
+               else
+                       screen(ctl, left);
+       }
+       fflush(stdout);
+       fclose(ctl->current_file);
+       ctl->current_file = NULL;
+       ctl->screen_start.line_num = ctl->screen_start.row_num = 0L;
+       ctl->context.line_num = ctl->context.row_num = 0L;
+}
+
 static void initterm(struct more_control *ctl)
 {
        int ret;
@@ -1903,10 +1965,6 @@ int main(int argc, char **argv)
        char *s;
        int chr;
        int left;
-       int print_names = 0;
-       int init = 0;
-       int search_at_start = 0;
-       int skip_file = 0;
        int start_at_line = 0;
        char *initbuf = NULL;
        struct more_control ctl = {
@@ -1959,10 +2017,10 @@ int main(int argc, char **argv)
                } else if (chr == '+') {
                        s = *ctl.file_names;
                        if (*++s == '/') {
-                               search_at_start++;
+                               ctl.search_at_start = 1;
                                initbuf = xstrdup(s + 1);
                        } else {
-                               init++;
+                               ctl.jump_at_start = 1;
                                for (start_at_line = 0; *s != '\0'; s++)
                                        if (isdigit(*s))
                                                start_at_line =
@@ -1986,7 +2044,7 @@ int main(int argc, char **argv)
                ctl.lines_per_screen = ctl.lines_per_page - 1;
        left = ctl.lines_per_screen;
        if (ctl.num_files > 1)
-               print_names++;
+               ctl.print_banner = 1;
        if (!ctl.no_tty_in && ctl.num_files == 0) {
                warnx(_("bad usage"));
                errtryhelp(EXIT_FAILURE);
@@ -2009,89 +2067,19 @@ int main(int argc, char **argv)
                if (ctl.no_tty_out)
                        copy_file(stdin);
                else {
-                       if ((chr = getc(ctl.current_file)) == '\f')
-                               more_clear_screen(&ctl);
-                       else {
-                               ungetc(chr, ctl.current_file);
-                               if (ctl.no_scroll && (chr != EOF)) {
-                                       if (ctl.clear_line_ends)
-                                               putp(ctl.go_home);
-                                       else
-                                               more_clear_screen(&ctl);
-                               }
-                       }
                        ctl.current_file = stdin;
-                       if (search_at_start) {
-                               free(ctl.previous_search);
-                               ctl.previous_search = xstrdup(initbuf);
-                               search(&ctl, initbuf, 1);
-                               if (ctl.no_scroll)
-                                       left--;
-                       } else if (init)
-                               skip_lines(&ctl, start_at_line);
-                       screen(&ctl, left);
+                       display_file(&ctl, initbuf, left);
                }
                ctl.no_tty_in = 0;
-               print_names++;
+               ctl.print_banner = 1;
                ctl.first_file = 0;
        }
 
        while (ctl.argv_position < ctl.num_files) {
-               checkf(&ctl, ctl.file_names[ctl.argv_position], &skip_file);
-               if (ctl.current_file != NULL) {
-                       ctl.context.line_num = ctl.context.row_num = 0;
-                       ctl.current_line = 0;
-                       if (ctl.first_file) {
-                               ctl.first_file = 0;
-                               if (search_at_start) {
-                                       free(ctl.previous_search);
-                                       ctl.previous_search = xstrdup(initbuf);
-                                       search(&ctl, initbuf, 1);
-                                       if (ctl.no_scroll)
-                                               left--;
-                               } else if (init)
-                                       skip_lines(&ctl, start_at_line);
-                       } else if (ctl.argv_position < ctl.num_files && !ctl.no_tty_out)
-                               left = more_key_command(&ctl, ctl.file_names[ctl.argv_position]);
-                       if (left != 0) {
-                               if ((ctl.no_scroll || skip_file)
-                                   && (ctl.file_size != LONG_MAX)) {
-                                       if (ctl.clear_line_ends)
-                                               putp(ctl.go_home);
-                                       else
-                                               more_clear_screen(&ctl);
-                               }
-                               if (print_names) {
-                                       if (ctl.bad_stdout)
-                                               erase_prompt(&ctl, 0);
-                                       if (ctl.clear_line_ends)
-                                               putp(ctl.erase_line);
-                                       fputs("::::::::::::::", stdout);
-                                       if (ctl.prompt_len > 14)
-                                               erase_prompt(&ctl, 14);
-                                       putchar('\n');
-                                       if (ctl.clear_line_ends)
-                                               putp(ctl.erase_line);
-                                       puts(ctl.file_names[ctl.argv_position]);
-                                       if (ctl.clear_line_ends)
-                                               putp(ctl.erase_line);
-                                       fputs("::::::::::::::\n", stdout);
-                                       if (left > ctl.lines_per_page - 4)
-                                               left = ctl.lines_per_page - 4;
-                               }
-                               if (ctl.no_tty_out)
-                                       copy_file(ctl.current_file);
-                               else
-                                       screen(&ctl, left);
-                       }
-                       fflush(stdout);
-                       fclose(ctl.current_file);
-                       ctl.current_file = NULL;
-                       ctl.screen_start.line_num = ctl.screen_start.row_num = 0L;
-                       ctl.context.line_num = ctl.context.row_num = 0L;
-               }
-               ctl.argv_position++;
+               checkf(&ctl, ctl.file_names[ctl.argv_position]);
+               display_file(&ctl, initbuf, left);
                ctl.first_file = 0;
+               ctl.argv_position++;
        }
        free(ctl.previous_search);
        free(initbuf);