Esempio n. 1
0
/*
 * Analogous to back_line(), but deals with "raw lines".
 * {{ This is supposed to be more efficient than back_line(). }}
 */
off_t
back_raw_line(off_t curr_pos, char **linep, int *line_lenp)
{
	int n;
	int c;
	off_t new_pos;

	if (curr_pos == -1 || curr_pos <= ch_zero() || ch_seek(curr_pos - 1))
		return (-1);

	n = size_linebuf;
	linebuf[--n] = '\0';
	for (;;) {
		c = ch_back_get();
		if (c == '\n' || ABORT_SIGS()) {
			/*
			 * This is the newline ending the previous line.
			 * We have hit the beginning of the line.
			 */
			new_pos = ch_tell() + 1;
			break;
		}
		if (c == EOI) {
			/*
			 * We have hit the beginning of the file.
			 * This must be the first line in the file.
			 * This must, of course, be the beginning of the line.
			 */
			new_pos = ch_zero();
			break;
		}
		if (n <= 0) {
			int old_size_linebuf = size_linebuf;
			char *fm;
			char *to;
			if (expand_linebuf()) {
				/*
				 * Overflowed the input buffer.
				 * Pretend the line ended here.
				 */
				new_pos = ch_tell() + 1;
				break;
			}
			/*
			 * Shift the data to the end of the new linebuf.
			 */
			for (fm = linebuf + old_size_linebuf - 1,
			    to = linebuf + size_linebuf - 1;
			    fm >= linebuf;  fm--, to--)
				*to = *fm;
			n = size_linebuf - old_size_linebuf;
		}
		linebuf[--n] = c;
	}
	if (linep != NULL)
		*linep = &linebuf[n];
	if (line_lenp != NULL)
		*line_lenp = size_linebuf - 1 - n;
	return (new_pos);
}
Esempio n. 2
0
/*
 * Make sure the screen is displayed.
 */
static void
make_display(void)
{
	/*
	 * If nothing is displayed yet, display starting from initial_scrpos.
	 */
	if (empty_screen()) {
		if (initial_scrpos.pos == -1)
			/*
			 * {{ Maybe this should be:
			 *    jump_loc(ch_zero(), jump_sline);
			 *    but this behavior seems rather unexpected
			 *    on the first screen. }}
			 */
			jump_loc(ch_zero(), 1);
		else
			jump_loc(initial_scrpos.pos, initial_scrpos.ln);
	} else if (screen_trashed) {
		int save_top_scroll = top_scroll;
		int save_ignore_eoi = ignore_eoi;
		top_scroll = 1;
		ignore_eoi = 0;
		if (screen_trashed == 2) {
			/*
			 * Special case used by ignore_eoi: re-open the input
			 * file and jump to the end of the file.
			 */
			reopen_curr_ifile();
			jump_forw();
		}
		repaint();
		top_scroll = save_top_scroll;
		ignore_eoi = save_ignore_eoi;
	}
}
Esempio n. 3
0
/*
 * Get the mark structure identified by a character.
 * The mark struct may come either from the mark table
 * or may be constructed on the fly for certain characters like ^, $.
 */
static struct mark *
getmark(int c)
{
	register struct mark *m;
	static struct mark sm;

	switch (c) {
	case '^':
		/*
		 * Beginning of the current file.
		 */
		m = &sm;
		m->m_scrpos.pos = ch_zero();
		m->m_scrpos.ln = 0;
		m->m_ifile = curr_ifile;
		break;
	case '$':
		/*
		 * End of the current file.
		 */
		if (ch_end_seek()) {
			error("Cannot seek to end of file", NULL_PARG);
			return (NULL);
		}
		m = &sm;
		m->m_scrpos.pos = ch_tell();
		m->m_scrpos.ln = sc_height-1;
		m->m_ifile = curr_ifile;
		break;
	case '.':
		/*
		 * Current position in the current file.
		 */
		m = &sm;
		get_scrpos(&m->m_scrpos);
		m->m_ifile = curr_ifile;
		break;
	case '\'':
		/*
		 * The "last mark".
		 */
		m = &marks[LASTMARK];
		break;
	default:
		/*
		 * Must be a user-defined mark.
		 */
		m = getumark(c);
		if (m == NULL)
			break;
		if (m->m_scrpos.pos == -1) {
			error("Mark not set", NULL_PARG);
			return (NULL);
		}
		break;
	}
	return (m);
}
Esempio n. 4
0
/*
 * Go to a mark.
 */
void
gomark(int c)
{
	struct mark *m;
	struct scrpos scrpos;

	m = getmark(c);
	if (m == NULL)
		return;

	/*
	 * If we're trying to go to the lastmark and
	 * it has not been set to anything yet,
	 * set it to the beginning of the current file.
	 */
	if (m == &marks[LASTMARK] && m->m_scrpos.pos == -1) {
		m->m_ifile = curr_ifile;
		m->m_scrpos.pos = ch_zero();
		m->m_scrpos.ln = jump_sline;
	}

	/*
	 * If we're using lmark, we must save the screen position now,
	 * because if we call edit_ifile() below, lmark will change.
	 * (We save the screen position even if we're not using lmark.)
	 */
	scrpos = m->m_scrpos;
	if (m->m_ifile != curr_ifile) {
		/*
		 * Not in the current file; edit the correct file.
		 */
		if (edit_ifile(m->m_ifile))
			return;
	}

	jump_loc(scrpos.pos, scrpos.ln);
}
Esempio n. 5
0
/*
 * Decode a "percent" prototype character.
 * A prototype string may include various "percent" escapes;
 * that is, a percent sign followed by a single letter.
 * Here we decode that letter and take the appropriate action,
 * usually by appending something to the message being built.
 */
static void
protochar(int c, int where)
{
	off_t pos;
	off_t len;
	int n;
	off_t linenum;
	off_t last_linenum;
	IFILE h;

#undef	PAGE_NUM
#define	PAGE_NUM(linenum)  ((((linenum) - 1) / (sc_height - 1)) + 1)

	switch (c) {
	case 'b':	/* Current byte offset */
		pos = curr_byte(where);
		if (pos != -1)
			ap_pos(pos);
		else
			ap_quest();
		break;
	case 'c':
		ap_int(hshift);
		break;
	case 'd':	/* Current page number */
		linenum = currline(where);
		if (linenum > 0 && sc_height > 1)
			ap_pos(PAGE_NUM(linenum));
		else
			ap_quest();
		break;
	case 'D':	/* Final page number */
		/* Find the page number of the last byte in the file (len-1). */
		len = ch_length();
		if (len == -1) {
			ap_quest();
		} else if (len == 0) {
			/* An empty file has no pages. */
			ap_pos(0);
		} else {
			linenum = find_linenum(len - 1);
			if (linenum <= 0)
				ap_quest();
			else
				ap_pos(PAGE_NUM(linenum));
		}
		break;
	case 'E':	/* Editor name */
		ap_str(editor);
		break;
	case 'f':	/* File name */
		ap_str(get_filename(curr_ifile));
		break;
	case 'F':	/* Last component of file name */
		ap_str(last_component(get_filename(curr_ifile)));
		break;
	case 'i':	/* Index into list of files */
		if (ntags())
			ap_int(curr_tag());
		else
			ap_int(get_index(curr_ifile));
		break;
	case 'l':	/* Current line number */
		linenum = currline(where);
		if (linenum != 0)
			ap_pos(linenum);
		else
			ap_quest();
		break;
	case 'L':	/* Final line number */
		len = ch_length();
		if (len == -1 || len == ch_zero() ||
		    (linenum = find_linenum(len)) <= 0)
			ap_quest();
		else
			ap_pos(linenum-1);
		break;
	case 'm':	/* Number of files */
		n = ntags();
		if (n)
			ap_int(n);
		else
			ap_int(nifile());
		break;
	case 'p':	/* Percent into file (bytes) */
		pos = curr_byte(where);
		len = ch_length();
		if (pos != -1 && len > 0)
			ap_int(percentage(pos, len));
		else
			ap_quest();
		break;
	case 'P':	/* Percent into file (lines) */
		linenum = currline(where);
		if (linenum == 0 ||
		    (len = ch_length()) == -1 || len == ch_zero() ||
		    (last_linenum = find_linenum(len)) <= 0)
			ap_quest();
		else
			ap_int(percentage(linenum, last_linenum));
		break;
	case 's':	/* Size of file */
	case 'B':
		len = ch_length();
		if (len != -1)
			ap_pos(len);
		else
			ap_quest();
		break;
	case 't':	/* Truncate trailing spaces in the message */
		while (mp > message && mp[-1] == ' ')
			mp--;
		*mp = '\0';
		break;
	case 'T':	/* Type of list */
		if (ntags())
			ap_str("tag");
		else
			ap_str("file");
		break;
	case 'x':	/* Name of next file */
		h = next_ifile(curr_ifile);
		if (h != NULL)
			ap_str(get_filename(h));
		else
			ap_quest();
		break;
	}
}