예제 #1
0
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;
	}
}
예제 #2
0
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);
}
예제 #3
0
파일: more.c 프로젝트: pali/util-linux
/* 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);
}