int read_command() { int total_bytes_read = bytes_in_buffer; int bytes_read = 0; int last_read_byte_pos = 0; while (true) { int end_of_line = find_end_of_line(helper_buffer, last_read_byte_pos, total_bytes_read); if (end_of_line == -1) { if (total_bytes_read > MAX_LINE_LENGTH) { bytes_in_buffer = 0; if (helper_buffer[bytes_read - 1]) { clean_stdin(); } fprintf(stderr, "%s\n", SYNTAX_ERROR_STR); fflush(stderr); return 0; } } else { bytes_in_buffer = total_bytes_read - end_of_line - 1; if (end_of_line > MAX_LINE_LENGTH) { fprintf(stderr, "%s\n", SYNTAX_ERROR_STR); fflush(stderr); bytes_read = 0; } else { prepare_line_buffer(line_buffer, helper_buffer, end_of_line); bytes_read = end_of_line; } clean_helepr_buffer(helper_buffer, end_of_line + 1, bytes_in_buffer); return bytes_read; } bytes_read = read(STDIN_FILENO, helper_buffer + total_bytes_read, MAX_LINE_LENGTH + 1); if (bytes_read == 0) { was_end_of_file = true; return 0; } else if (bytes_read == -1) { bytes_read = 0; continue; } last_read_byte_pos = total_bytes_read; total_bytes_read += bytes_read; } }
int main(int argc, char **argv) { FILE *f; char *s; char *p; int ch; int left; int prnames = 0; int initopt = 0; int srchopt = 0; int clearit = 0; int initline = 0; char initbuf[INIT_BUF]; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); nfiles = argc; fnames = argv; setlocale(LC_ALL, ""); initterm (); /* Auto set no scroll on when binary is called page */ if (!(strcmp(program_invocation_short_name, "page"))) noscroll++; prepare_line_buffer(); nscroll = Lpp/2 - 1; if (nscroll <= 0) nscroll = 1; if ((s = getenv("MORE")) != NULL) argscan(s); while (--nfiles > 0) { if ((ch = (*++fnames)[0]) == '-') { argscan(*fnames+1); } else if (ch == '+') { s = *fnames; if (*++s == '/') { srchopt++; for (++s, p = initbuf; p < initbuf + (INIT_BUF - 1) && *s != '\0';) *p++ = *s++; *p = '\0'; } else { initopt++; for (initline = 0; *s != '\0'; s++) if (isdigit (*s)) initline = initline*10 + *s -'0'; --initline; } } else break; } /* allow clreol only if Home and eraseln and EodClr strings are * defined, and in that case, make sure we are in noscroll mode */ if (clreol) { if((Home == NULL) || (*Home == '\0') || (eraseln == NULL) || (*eraseln == '\0') || (EodClr == NULL) || (*EodClr == '\0') ) clreol = 0; else noscroll = 1; } if (dlines == 0) dlines = Lpp - 1; /* was: Lpp - (noscroll ? 1 : 2) */ left = dlines; if (nfiles > 1) prnames++; if (!no_intty && nfiles == 0) usage(stderr); else f = stdin; if (!no_tty) { signal(SIGQUIT, onquit); signal(SIGINT, end_it); #ifdef SIGWINCH signal(SIGWINCH, chgwinsz); #endif /* SIGWINCH */ if (signal (SIGTSTP, SIG_IGN) == SIG_DFL) { signal(SIGTSTP, onsusp); catch_susp++; } stty (fileno(stderr), &otty); } if (no_intty) { if (no_tty) copy_file (stdin); else { if ((ch = Getc (f)) == '\f') doclear(); else { Ungetc (ch, f); if (noscroll && (ch != EOF)) { if (clreol) home (); else doclear (); } } if (srchopt) { search (initbuf, stdin, 1); if (noscroll) left--; } else if (initopt) skiplns (initline, stdin); screen (stdin, left); } no_intty = 0; prnames++; firstf = 0; } while (fnum < nfiles) { if ((f = checkf (fnames[fnum], &clearit)) != NULL) { context.line = context.chrctr = 0; Currline = 0; if (firstf) sigsetjmp (restore, 1); if (firstf) { firstf = 0; if (srchopt) { search (initbuf, f, 1); if (noscroll) left--; } else if (initopt) skiplns (initline, f); } else if (fnum < nfiles && !no_tty) { sigsetjmp (restore, 1); left = command (fnames[fnum], f); } if (left != 0) { if ((noscroll || clearit) && (file_size != LONG_MAX)) { if (clreol) home (); else doclear (); } if (prnames) { if (bad_so) erasep (0); if (clreol) cleareol (); putsout("::::::::::::::"); if (promptlen > 14) erasep (14); putchar('\n'); if(clreol) cleareol(); puts(fnames[fnum]); if(clreol) cleareol(); puts("::::::::::::::"); if (left > Lpp - 4) left = Lpp - 4; } if (no_tty) copy_file (f); else { within++; screen(f, left); within = 0; } } sigsetjmp (restore, 1); fflush(stdout); fclose(f); screen_start.line = screen_start.chrctr = 0L; context.line = context.chrctr = 0L; } fnum++; firstf = 0; } reset_tty (); exit(EXIT_SUCCESS); }
/* Get a logical line */ static int get_line(register FILE *f, int *length) { int c; char *p; int column; static int colflg; #ifdef HAVE_WIDECHAR size_t i; wchar_t wc; int wc_width; mbstate_t state, state_bak; /* Current status of the stream. */ char mbc[MB_LEN_MAX]; /* Buffer for one multibyte char. */ size_t mblength; /* Byte length of multibyte char. */ size_t mbc_pos = 0; /* Position of the MBC. */ int use_mbc_buffer_flag = 0; /* If 1, mbc has data. */ int break_flag = 0; /* If 1, exit while(). */ long file_pos_bak = Ftell(f); memset(&state, '\0', sizeof(mbstate_t)); #endif prepare_line_buffer(); p = Line; column = 0; c = Getc(f); if (colflg && c == '\n') { Currline++; c = Getc(f); } while (p < &Line[LineLen - 1]) { #ifdef HAVE_WIDECHAR if (fold_opt && use_mbc_buffer_flag && MB_CUR_MAX > 1) { use_mbc_buffer_flag = 0; state_bak = state; mbc[mbc_pos++] = c; process_mbc: mblength = mbrtowc(&wc, mbc, mbc_pos, &state); switch (mblength) { case (size_t)-2: /* Incomplete multibyte character. */ use_mbc_buffer_flag = 1; state = state_bak; break; case (size_t)-1: /* Invalid as a multibyte character. */ *p++ = mbc[0]; state = state_bak; column++; file_pos_bak++; if (column >= Mcol) { Fseek(f, file_pos_bak); } else { memmove(mbc, mbc + 1, --mbc_pos); if (mbc_pos > 0) { mbc[mbc_pos] = '\0'; goto process_mbc; } } break; default: wc_width = wcwidth(wc); if (column + wc_width > Mcol) { Fseek(f, file_pos_bak); break_flag = 1; } else { for (i = 0; p < &Line[LineLen - 1] && i < mbc_pos; i++) *p++ = mbc[i]; if (wc_width > 0) column += wc_width; } } if (break_flag || column >= Mcol) break; c = Getc(f); continue; } #endif /* HAVE_WIDECHAR */ if (c == EOF) { if (p > Line) { *p = '\0'; *length = p - Line; return (column); } *length = p - Line; return (EOF); } if (c == '\n') { Currline++; break; } *p++ = c; #if 0 if (c == '\033') { /* ESC */ c = Getc(f); while (c > ' ' && c < '0' && p < &Line[LineLen - 1]) { *p++ = c; c = Getc(f); } if (c >= '0' && c < '\177' && p < &Line[LineLen - 1]) { *p++ = c; c = Getc(f); continue; } } #endif /* 0 */ if (c == '\t') { if (!hardtabs || (column < promptlen && !hard)) { if (hardtabs && eraseln && !dumb) { column = 1 + (column | 7); putstring(eraseln); promptlen = 0; } else { for (--p; p < &Line[LineLen - 1];) { *p++ = ' '; if ((++column & 7) == 0) break; } if (column >= promptlen) promptlen = 0; } } else column = 1 + (column | 7); } else if (c == '\b' && column > 0) { column--; } else if (c == '\r') { int next = Getc(f); if (next == '\n') { p--; Currline++; break; } Ungetc(next, f); column = 0; } else if (c == '\f' && stop_opt) { p[-1] = '^'; *p++ = 'L'; column += 2; Pause++; } else if (c == EOF) { *length = p - Line; return (column); } else { #ifdef HAVE_WIDECHAR if (fold_opt && MB_CUR_MAX > 1) { memset(mbc, '\0', MB_LEN_MAX); mbc_pos = 0; mbc[mbc_pos++] = c; state_bak = state; mblength = mbrtowc(&wc, mbc, mbc_pos, &state); /* The value of mblength is always less than 2 here. */ switch (mblength) { case (size_t)-2: p--; file_pos_bak = Ftell(f) - 1; state = state_bak; use_mbc_buffer_flag = 1; break; case (size_t)-1: state = state_bak; column++; break; default: wc_width = wcwidth(wc); if (wc_width > 0) column += wc_width; } } else #endif /* HAVE_WIDECHAR */ { if (isprint(c)) column++; } } if (column >= Mcol && fold_opt) break; #ifdef HAVE_WIDECHAR if (use_mbc_buffer_flag == 0 && p >= &Line[LineLen - 1 - 4]) /* don't read another char if there is no space for * whole multibyte sequence */ break; #endif c = Getc(f); } if (column >= Mcol && Mcol > 0) { if (!Wrap) { *p++ = '\n'; } } colflg = column == Mcol && fold_opt; if (colflg && eatnl && Wrap) { *p++ = '\n'; /* simulate normal wrap */ } *length = p - Line; *p = 0; return (column); }