Exemplo n.º 1
0
/*
 * CheckCurrentFcbCapacity - check if fcb has exceeded its capacity; if so,
 *                           split it
 */
vi_rc CheckCurrentFcbCapacity( void )
{
    int         bc, bl;
    line        *cl;
    linenum     l;
    vi_rc       rc;

    /*
     * check if fcb is full
     */
    if( FcbSize( CurrentFcb ) <= MAX_IO_BUFFER ) {
        return( ERR_NO_ERR );
    }
    FetchFcb( CurrentFcb );

    /*
     * can't take it, so split it
     */
    cl = CurrentFcb->lines.head;
    bl = CurrentFcb->byte_cnt / 2;
    l = CurrentFcb->start_line;
    for( bc = cl->len + 1; bc < bl; bc += cl->len + 1 ) {
        cl = cl->next;
        l++;
    }
    rc = SplitFcbAtLine( l, CurrentFile, CurrentFcb );
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }

    /*
     * check if current line is in new fcb, if so, switch to new fcb;
     * as well, new fcb had better have the same display status as the old
     */
    CurrentFcb->next->on_display = CurrentFcb->on_display;
    if( CurrentPos.line > CurrentFcb->end_line ) {
        CurrentFcb = CurrentFcb->next;
        FetchFcb( CurrentFcb );
    }
    return( ERR_NO_ERR );

} /* CheckCurrentFcbCapacity */
Exemplo n.º 2
0
/*
 * InsertLines - insert a set of lines after specified number in current file
 */
vi_rc InsertLines( linenum s, fcb_list *fcblist, undo_stack *us )
{
    fcb         *sfcb, *cfcb;
    linenum     l, e;
    vi_rc       rc;

    rc = ModificationTest();
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }
    if( s < 0 ) {
        return( ERR_NO_SUCH_LINE );
    }

    /*
     * find the number of lines inserted
     */
    e = 0;
    for( cfcb = fcblist->head; cfcb != NULL; cfcb = cfcb->next ) {
        e += cfcb->end_line - cfcb->start_line + 1;
    }
    e += s;

    /*
     * see if there is a null fcb at the head; if so, ditch
     * the null fcb and then reset line ranges
     */
    if( CurrentFile->fcbs.head->nullfcb ) {
        FreeEntireFcb( CurrentFile->fcbs.head );
        CurrentFile->fcbs = *fcblist;
        e = e - s;
        s = 0;
    /*
     * if we are to insert after line 0, then make this block of
     * fcbs the first set in the text
     */
    } else if( s == 0 ) {
        fcblist->tail->next = CurrentFile->fcbs.head;
        CurrentFile->fcbs.head->prev = fcblist->tail;
        CurrentFile->fcbs.head = fcblist->head;
    } else {
        /*
         * if we are inserting after the last fcb in the file,
         * make this block of fcbs the last set in the text
         */
        rc = FindFcbWithLine( s + 1, CurrentFile, &sfcb );
        if( rc != ERR_NO_ERR ) {
            if( rc != ERR_NO_SUCH_LINE ) {
                return( rc );
            }
            fcblist->head->prev = CurrentFile->fcbs.tail;
            CurrentFile->fcbs.tail->next = fcblist->head;
            CurrentFile->fcbs.tail = fcblist->tail;
        /*
         * put the lines after the line to be have text inserted
         * into a new fcb, then insert the block of fcb's after
         * the fcb containing the line to have text inserted
         */
        } else {
            rc = SplitFcbAtLine( s + 1, CurrentFile, sfcb );
            if( rc > ERR_NO_ERR ) {
                return( rc );
            }
            /*
             * line we want to split at is already the first line
             * in the fcb, so chain the new fcb block before
             * the fcb containg the line we want to split at
             */
            if( rc == NO_SPLIT_CREATED_AT_START_LINE ) {
                if( sfcb->prev != NULL ) {
                    sfcb->prev->next = fcblist->head;
                }
                fcblist->head->prev = sfcb->prev;
                sfcb->prev = fcblist->tail;
                fcblist->tail->next = sfcb;
            /*
             * chain the new fcb block after the fcb that used
             * to containing the line we wanted to split at, and
             * before the new fcb containing the line we want
             * to split at
             */
            } else {
                if( rc == NO_SPLIT_CREATED_AT_END_LINE ) {
//                  Die( "Impossible, can't be past last line");
                }
                if( sfcb->next != NULL ) {
                    sfcb->next->prev = fcblist->tail;
                }
                fcblist->tail->next = sfcb->next;
                sfcb->next = fcblist->head;
                fcblist->head->prev = sfcb;
            }
        }
    }

    /*
     * now, resequence line numbers and set proper file ptr
     */
    for( cfcb = fcblist->head; cfcb != NULL; cfcb = cfcb->next ) {
        cfcb->f = CurrentFile;
        l = cfcb->end_line - cfcb->start_line;
        if( cfcb->prev != NULL ) {
            cfcb->start_line = cfcb->prev->end_line + 1;
        } else {
            cfcb->start_line = 1;
        }
        cfcb->end_line = cfcb->start_line + l;
    }

    /*
     * finish up: collect fcbs, point to corrent line, and
     * build undo for operation
     */
    rc = MergeAllFcbs( &CurrentFile->fcbs );
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }
    StartUndoGroup( us );
    rc = ValidateCurrentLine();
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }
    Modified( true );
    UndoInsert( s + 1, e, us );
    EndUndoGroup( us );

    return( ERR_NO_ERR );

} /* InsertLines */