Пример #1
0
Файл: conv.c Проект: fishman/nvi
int 
default_char2int(SCR *sp, const char * str, ssize_t len, CONVWIN *cw, 
		size_t *tolen, CHAR_T **dst, char *enc)
{
    int i = 0, j;
    CHAR_T **tostr = (CHAR_T **)&cw->bp1;
    size_t  *blen = &cw->blen1;
    mbstate_t mbs;
    size_t   n;
    ssize_t  nlen = len;
    char *src = (char *)str;
    iconv_t	id = (iconv_t)-1;
    char	buffer[CONV_BUFFER_SIZE];
    size_t	left = len;
    int		error = 1;

    MEMSET(&mbs, 0, 1);
    BINC_RETW(NULL, *tostr, *blen, nlen);

#ifdef USE_ICONV
    if (strcmp(nl_langinfo(CODESET), enc)) {
	id = iconv_open(nl_langinfo(CODESET), enc);
	if (id == (iconv_t)-1)
	    goto err;
	CONVERT(str, left, src, len);
    }
#endif

    for (i = 0, j = 0; j < len; ) {
	n = mbrtowc((*tostr)+i, src+j, len-j, &mbs);
	/* NULL character converted */
	if (n == -2) error = -(len-j);
	if (n == -1 || n == -2) goto err;
	if (n == 0) n = 1;
	j += n;
	if (++i >= *blen) {
	    nlen += 256;
	    BINC_RETW(NULL, *tostr, *blen, nlen);
	}
	if (id != (iconv_t)-1 && j == len && left) {
	    CONVERT(str, left, src, len);
	    j = 0;
	}
    }
    *tolen = i;

    if (id != (iconv_t)-1)
	iconv_close(id);

    *dst = cw->bp1;

    return 0;
err:
    *tolen = i;
    if (id != (iconv_t)-1)
	iconv_close(id);
    *dst = cw->bp1;

    return error;
}
Пример #2
0
/*
 * v_curword --
 *	Get the word (tagstring, actually) the cursor is on.
 *
 * PUBLIC: int v_curword __P((SCR *));
 */
int
v_curword(SCR *sp)
{
	VI_PRIVATE *vip;
	size_t beg, end, len;
	int moved;
	CHAR_T *p;

	if (db_get(sp, sp->lno, DBG_FATAL, &p, &len))
		return (1);

	/*
	 * !!!
	 * Historically, tag commands skipped over any leading whitespace
	 * characters.  Make this true in general when using cursor words.
	 * If movement, getting a cursor word implies moving the cursor to
	 * its beginning.  Refresh now.
	 *
	 * !!!
	 * Find the beginning/end of the keyword.  Keywords are currently
	 * used for cursor-word searching and for tags.  Historical vi
	 * only used the word in a tag search from the cursor to the end
	 * of the word, i.e. if the cursor was on the 'b' in " abc ", the
	 * tag was "bc".  For consistency, we make cursor word searches
	 * follow the same rule.
	 */
	for (moved = 0,
	    beg = sp->cno; beg < len && ISSPACE(p[beg]); moved = 1, ++beg);
	if (beg >= len) {
		msgq(sp, M_BERR, "212|Cursor not in a word");
		return (1);
	}
	if (moved) {
		sp->cno = beg;
		(void)vs_refresh(sp, 0);
	}

	/*
	 * Find the end of the word.
	 *
	 * !!!
	 * Historically, vi accepted any non-blank as initial character
	 * when building up a tagstring.  Required by IEEE 1003.1-2001.
	 */
	for (end = beg; ++end < len && inword(p[end]););

	vip = VIP(sp);
	vip->klen = len = (end - beg);
	BINC_RETW(sp, vip->keyw, vip->keywlen, len+1);
	MEMMOVE(vip->keyw, p + beg, len);
	vip->keyw[len] = '\0';				/* XXX */
	return (0);
}
Пример #3
0
/*
 * txt_dent --
 *	Handle ^D outdents.
 *
 * Ex version of vi/v_ntext.c:txt_dent().  See that code for the (usual)
 * ranting and raving.  This is a fair bit simpler as ^T isn't special.
 */
static int
txt_dent(SCR *sp, TEXT *tp)
{
	u_long sw, ts;
	size_t cno, off, scno, spaces, tabs;

	ts = O_VAL(sp, O_TABSTOP);
	sw = O_VAL(sp, O_SHIFTWIDTH);

	/* Get the current screen column. */
	for (off = scno = 0; off < tp->len; ++off)
		if (tp->lb[off] == '\t')
			scno += COL_OFF(scno, ts);
		else
			++scno;

	/* Get the previous shiftwidth column. */
	cno = scno--;
	scno -= scno % sw;

	/*
	 * Since we don't know what comes before the character(s) being
	 * deleted, we have to resolve the autoindent characters .  The
	 * example is a <tab>, which doesn't take up a full shiftwidth
	 * number of columns because it's preceded by <space>s.  This is
	 * easy to get if the user sets shiftwidth to a value less than
	 * tabstop, and then uses ^T to indent, and ^D to outdent.
	 *
	 * Count up spaces/tabs needed to get to the target.
	 */
	for (cno = 0, tabs = 0; cno + COL_OFF(cno, ts) <= scno; ++tabs)
		cno += COL_OFF(cno, ts);
	spaces = scno - cno;

	/* Make sure there's enough room. */
	BINC_RETW(sp, tp->lb, tp->lb_len, tabs + spaces + 1);

	/* Adjust the final ai character count. */
	tp->ai = tabs + spaces;

	/* Enter the replacement characters. */
	for (tp->len = 0; tabs > 0; --tabs)
		tp->lb[tp->len++] = '\t';
	for (; spaces > 0; --spaces)
		tp->lb[tp->len++] = ' ';
	return (0);
}
Пример #4
0
static int 
raw2int(SCR *sp, const char * str, ssize_t len, CONVWIN *cw, size_t *tolen,
	const CHAR_T **dst)
{
    int i;
    CHAR_T **tostr = (CHAR_T **)(void *)&cw->bp1;
    size_t  *blen = &cw->blen1;

    BINC_RETW(NULL, *tostr, *blen, len);

    *tolen = len;
    for (i = 0; i < len; ++i)
	(*tostr)[i] = (u_char) str[i];

    *dst = cw->bp1;

    return 0;
}
Пример #5
0
/*
 * ex_move -- :[line [,line]] mo[ve] line
 *	Move selected lines.
 *
 * PUBLIC: int ex_move __P((SCR *, EXCMD *));
 */
int
ex_move(SCR *sp, EXCMD *cmdp)
{
	LMARK *lmp;
	MARK fm1, fm2;
	db_recno_t cnt, diff, fl, tl, mfl, mtl;
	size_t blen, len;
	int mark_reset;
	CHAR_T *bp;
	CHAR_T *p;

	NEEDFILE(sp, cmdp);

	/*
	 * It's not possible to move things into the area that's being
	 * moved.
	 */
	fm1 = cmdp->addr1;
	fm2 = cmdp->addr2;
	if (cmdp->lineno >= fm1.lno && cmdp->lineno <= fm2.lno) {
		msgq(sp, M_ERR, "139|Destination line is inside move range");
		return (1);
	}

	/*
	 * Log the positions of any marks in the to-be-deleted lines.  This
	 * has to work with the logging code.  What happens is that we log
	 * the old mark positions, make the changes, then log the new mark
	 * positions.  Then the marks end up in the right positions no matter
	 * which way the log is traversed.
	 *
	 * XXX
	 * Reset the MARK_USERSET flag so that the log can undo the mark.
	 * This isn't very clean, and should probably be fixed.
	 */
	fl = fm1.lno;
	tl = cmdp->lineno;

	/* Log the old positions of the marks. */
	mark_reset = 0;
	LIST_FOREACH(lmp, &sp->ep->marks, q)
		if (lmp->name != ABSMARK1 &&
		    lmp->lno >= fl && lmp->lno <= tl) {
			mark_reset = 1;
			F_CLR(lmp, MARK_USERSET);
			(void)log_mark(sp, lmp);
		}

	/* Get memory for the copy. */
	GET_SPACE_RETW(sp, bp, blen, 256);

	/* Move the lines. */
	diff = (fm2.lno - fm1.lno) + 1;
	if (tl > fl) {				/* Destination > source. */
		mfl = tl - diff;
		mtl = tl;
		for (cnt = diff; cnt--;) {
			if (db_get(sp, fl, DBG_FATAL, &p, &len))
				return (1);
			BINC_RETW(sp, bp, blen, len);
			MEMCPYW(bp, p, len);
			if (db_append(sp, 1, tl, bp, len))
				return (1);
			if (mark_reset)
				LIST_FOREACH(lmp, &sp->ep->marks, q)
					if (lmp->name != ABSMARK1 &&
					    lmp->lno == fl)
						lmp->lno = tl + 1;
			if (db_delete(sp, fl))
				return (1);
		}
	} else {				/* Destination < source. */