Exemplo n.º 1
0
/*
 * FindFcbWithLine - find the fcb with the specified line
 */
vi_rc FindFcbWithLine( linenum lineno, file *cfile, fcb **fb )
{
    bool    lastflag = false;
    fcb     *tfcb, *ofcb;
    vi_rc   rc;

    /*
     * are we looking for the last line?
     */
    if( lineno < 0 ) {
        lastflag = true;
        lineno = MAX_LONG;
    }
    if( lineno < 1 ) {
        return( ERR_NO_SUCH_LINE );
    }
    if( cfile == NULL ) {
        return( ERR_NO_FILE );
    }

    /*
     * run through all possible fcb's
     */
    tfcb = cfile->fcbs.head;
    if( tfcb == NULL ) {
        return( ERR_NO_SUCH_LINE );
    }
    for( ;; ) {

        if( tfcb->end_line >= lineno ) {
            *fb = tfcb;
            FetchFcb( tfcb );
            return( ERR_NO_ERR );
        }
        ofcb = tfcb;
        tfcb = ofcb->next;
        if( tfcb == NULL ) {
            if( !cfile->bytes_pending ) {
                if( lastflag ) {
                    *fb = ofcb;
                    FetchFcb( ofcb );
                    return( ERR_NO_ERR );
                }
                return( ERR_NO_SUCH_LINE );
            }
            if( EditFlags.Verbose ) {
                Message1( "At line %l", ofcb->end_line );
            }
            rc = ReadFcbData( cfile, NULL );
            if( rc != ERR_NO_ERR && rc != END_OF_FILE ) {
                return( rc );
            }
            tfcb = cfile->fcbs.tail;
        }
    }

} /* FindFcbWithLine */
Exemplo n.º 2
0
/*
 * GimmeNextLinePtr - get pointer to next line
 */
vi_rc GimmeNextLinePtr( file *cfile, fcb **cfcb, line **cline )
{
    vi_rc   rc;
    fcb     *ofcb;

    /*
     * get next line pointer; if not null, go back
     */
    *cline = (*cline)->next;
    if( *cline != NULL ) {
        return( ERR_NO_ERR );
    }

    /*
     * get next fcb pointer; if not null, get first line and go back
     */
    *cfcb = (*cfcb)->next;
    if( *cfcb != NULL ) {
        FetchFcb( *cfcb );
        *cline = (*cfcb)->lines.head;
        return( ERR_NO_ERR );
    }

    /*
     * get next fcb if can; then get first line and go back
     */
    if( cfile->bytes_pending ) {
        ofcb = cfile->fcbs.tail;
        rc = ReadFcbData( cfile );
        if( rc > ERR_NO_ERR ) {
            return( rc );
        }
        *cfcb = cfile->fcbs.tail;
        if( *cfcb != ofcb ) {
            while( (*cfcb)->prev != ofcb ) {
                *cfcb = (*cfcb)->prev;
            }
        }
        FetchFcb( *cfcb );
        *cline = (*cfcb)->lines.head;
        return( ERR_NO_ERR );
    }

    /*
     * no such line
     */
    *cfcb = NULL;
    *cline = NULL;
    return( ERR_NO_MORE_LINES );

} /* GimmeNextLinePtr */
Exemplo n.º 3
0
/*
 * GimmePrevLinePtr - get pointer to previous line
 */
vi_rc GimmePrevLinePtr( fcb **cfcb, line **cline )
{

    /*
     * get next line pointer; if not null, go back
     */
    *cline = (*cline)->prev;
    if( *cline != NULL ) {
        return( ERR_NO_ERR );
    }

    /*
     * get next fcb pointer; if not null, get first line and go back
     */
    *cfcb = (*cfcb)->prev;
    if( *cfcb != NULL ) {
        FetchFcb( *cfcb );
        *cline = (*cfcb)->lines.tail;
        return( ERR_NO_ERR );
    }

    /*
     * no such line
     */
    *cfcb = NULL;
    *cline = NULL;
    return( ERR_NO_MORE_LINES );

} /* GimmePrevLinePtr */
Exemplo n.º 4
0
/*
 * ReplaceCurrentLine - replace current line with work line
 */
vi_rc ReplaceCurrentLine( void )
{
    int         extra;
    line        *tmp;

    /*
     * add extra space to fcb
     */
    FetchFcb( CurrentFcb );
    extra = WorkLine->len - CurrentLine->len;
    CurrentFcb->byte_cnt += extra;
    CurrentFcb->nullfcb = false;

    /*
     * copy new data in
     */
    tmp = LineAlloc( WorkLine->data, WorkLine->len );
    tmp->u.ld.mark = CurrentLine->u.ld.mark;
    ReplaceLLItem( (ss **)&CurrentFcb->lines.head, (ss **)&CurrentFcb->lines.tail,
                   (ss *)CurrentLine, (ss *)tmp );
    MemFree( CurrentLine );
    CurrentLine = tmp;

    WorkLine->len = -1;

    return( CheckCurrentFcbCapacity() );

} /* ReplaceCurrentLine */
Exemplo n.º 5
0
/*
 * duplicateFcb - do just that
 */
static void duplicateFcb( fcb *cfcb, fcb **dfcb )
{
    line        *cline, *nline;

    /*
     * get fcb and create a new one
     */
    FetchFcb( cfcb );
    cfcb->non_swappable = TRUE;
    *dfcb = FcbAlloc( NULL );
    (*dfcb)->start_line = cfcb->start_line;
    (*dfcb)->end_line = cfcb->end_line;
    (*dfcb)->byte_cnt = cfcb->byte_cnt;
    (*dfcb)->lines.head = (*dfcb)->lines.tail = NULL;

    /*
     * copy all lines
     */
    for( cline = cfcb->lines.head; cline != NULL; cline = cline->next ) {
        nline = LineAlloc( cline->data, cline->len );
        AddLLItemAtEnd( (ss **)&((*dfcb)->lines.head), (ss **)&((*dfcb)->lines.tail),
            (ss *)nline );
    }

    cfcb->non_swappable = FALSE;
    (*dfcb)->non_swappable = FALSE;

} /* duplicateFcb */
Exemplo n.º 6
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.º 7
0
/*
 * CreateNullLine - put a single null line in an fcb
 */
void CreateNullLine( fcb *cfcb )
{
    line        *cline;

    cline = LineAlloc( NULL, 0 );
    FetchFcb( cfcb );
    AddLLItemAtEnd( (ss **)&(cfcb->lines.head), (ss **)&(cfcb->lines.tail), (ss *)cline );
    cfcb->byte_cnt = 1;
    cfcb->start_line = cfcb->end_line = 1;
    cfcb->nullfcb = TRUE;

} /* CreateNullLine */
Exemplo n.º 8
0
/*
 * JoinFcbs - join two fcbs
 */
static vi_rc JoinFcbs( fcb *fcb1, fcb *fcb2 )
{
    unsigned    j, k;

    /*
     * see if we can merge them
     */
    if( fcb1->end_line != (fcb2->start_line - 1) ) {
        return( COULD_NOT_MERGE_FCBS );
    }
    j = FcbSize( fcb1 );
    k = FcbSize( fcb2 );
    if( j + k > (unsigned) MAX_IO_BUFFER ) {
        return( COULD_NOT_MERGE_FCBS );
    }

    /*
     * get fcb's if swapped
     */
    FetchFcb( fcb1 );
    fcb1->non_swappable = TRUE;
    FetchFcb( fcb2 );
    fcb1->non_swappable = FALSE;

    /*
     * update byte count and line numbers
     */
    fcb1->byte_cnt += fcb2->byte_cnt;
    fcb1->end_line = fcb2->end_line;

    /*
     * merge the two sets of lines
     */
    fcb1->lines.tail->next = fcb2->lines.head;
    fcb2->lines.head->prev = fcb1->lines.tail;
    fcb1->lines.tail = fcb2->lines.tail;
    return( ERR_NO_ERR );

} /* JoinFcbs */
Exemplo n.º 9
0
/*
 * SwitchSavebuf - switch current save buffer
 */
vi_rc SwitchSavebuf( void )
{
    int         buf, i;
    linenum     lcnt;
    savebuf     *tmp;
    char        *data;
    fcb         *cfcb;

    /*
     * validate savebuf
     */
    buf = -1;
    for( i = 0; i < MAX_SAVEBUFS; i++ ) {
        if( LastEvent == SavebufBound[i] ){
            buf = i;
            break;
        }
    }
    if( buf < 0 ) {
        return( ERR_NO_ERR );
    }
    CurrentSavebuf = buf;
    tmp = &Savebufs[buf];
    data = NULL;
    switch( tmp->type ) {
    case SAVEBUF_NOP:
        Message1( "Buffer %d now active. (empty buffer)", buf + 1 );
        return( DO_NOT_CLEAR_MESSAGE_WINDOW );
    case SAVEBUF_LINE:
        data = tmp->u.data;
        Message1( "Buffer %d active, %d characters:", buf + 1,
                  strlen( tmp->u.data ) );
        break;
    case SAVEBUF_FCBS:
        cfcb = tmp->u.fcbs.head;
        FetchFcb( cfcb );
        data = cfcb->lines.head->data;
        lcnt = 0;
        for( ; cfcb != NULL; cfcb = cfcb->next ) {
            lcnt += cfcb->end_line - cfcb->start_line + 1;
        }
        Message1( "Buffer %d active, %l lines:", buf + 1, lcnt );
        break;
    }
    Message2( "\"%s\"", data );

    return( DO_NOT_CLEAR_MESSAGE_WINDOW );

} /* SwitchSavebuf */
Exemplo n.º 10
0
/*
 * GimmeLinePtrFromFcb - get a line pointer from a specified fcb
 */
vi_rc GimmeLinePtrFromFcb( linenum lineno, fcb *cfcb , line **res )
{
    linenum     linecnt;
    line        *tmp;

    if( lineno < 1 ) {
        return( ERR_NO_SUCH_LINE );
    }
    FetchFcb( cfcb );
    linecnt = cfcb->start_line;
    tmp = cfcb->lines.head;

    while( linecnt != lineno ) {
        linecnt++;
        tmp = tmp->next;
    }

    *res = tmp;

    return( ERR_NO_ERR );

} /* GimmeLinePtrFromFcb */
Exemplo n.º 11
0
/*
 * AddNewLineAroundCurrent - put a new line on either side of the current line
 */
void AddNewLineAroundCurrent( char *data, int copylen, insert_dir dir )
{
    bool        wasnull;
    /*
     * if inserting into a null fcb, clean it up
     */
    FetchFcb( CurrentFcb );
    wasnull = CurrentFcb->nullfcb;
    if( wasnull ) {
        MemFree( CurrentFcb->lines.head );
        CurrentFcb->lines.head = CurrentFcb->lines.tail = NULL;
        CurrentFcb->nullfcb = FALSE;
        CurrentFcb->byte_cnt = 0;
        CurrentFcb->end_line = 0;
    }

    /*
     * add the line
     */
    InsertNewLine( CurrentLine, &CurrentFcb->lines, data, copylen,dir );
    CurrentFcb->byte_cnt += copylen + 1;
    CurrentFcb->end_line += 1;

    /*
     * update line info
     */
    if( wasnull ) {
        CurrentLine = CurrentFcb->lines.head;
        SetCurrentLineNumber( 1 );
    } else {
        if( dir == INSERT_BEFORE ) {
            SetCurrentLineNumber( CurrentPos.line + 1 );
        }
        UpdateLineNumbers( 1L, CurrentFcb->next );
    }
    CheckCurrentFcbCapacity();

} /* AddNewLineAroundCurrent */
Exemplo n.º 12
0
/*
 * GetSavebufString - get a string made up of stuff in a savebuf
 */
vi_rc GetSavebufString( char **data )
{
#ifdef __WIN__
    savebuf     clip;
#endif
    savebuf     *tmp;
    fcb         *cfcb;
    line        *cline;
    vi_rc       rc;
    long        len;

    /*
     * fetch the savebuf
     */
    rc = DoSavebufNumber();
    if( rc != GOT_A_SAVEBUF ) {
        if( rc == ERR_NO_ERR ) {
            rc = DO_NOT_CLEAR_MESSAGE_WINDOW;
        }
        return( rc );
    }
#ifdef __WIN__
    if( SavebufNumber == CLIPBOARD_SAVEBUF ) {
        rc = GetClipboardSavebuf( &clip );
        if( rc != ERR_NO_ERR ) {
            return( rc );
        }
        tmp = &clip;
    } else
#endif
    if( SavebufNumber >= MAX_SAVEBUFS ) {
        tmp = &SpecialSavebufs[SavebufNumber - MAX_SAVEBUFS];
    } else {
        tmp = &Savebufs[SavebufNumber];
    }
    SavebufNumber = NO_SAVEBUF;

    /*
     * get length of stuff
     */
    len = 0L;
    switch( tmp->type ) {
    case SAVEBUF_NOP:
        return( ERR_EMPTY_SAVEBUF );
    case SAVEBUF_LINE:
        len = strlen( tmp->u.data );
        break;
    case SAVEBUF_FCBS:
        for( cfcb = tmp->u.fcbs.head; cfcb != NULL; cfcb = cfcb->next ) {
            len += FcbSize( cfcb );
        }
        break;
    }
    rc = ERR_NO_ERR;
    if( len > MAX_STR * 4 ) {
        rc = ERR_SAVEBUF_TOO_BIG;
    } else {
        *data = MemAlloc( len );
        switch( tmp->type ) {
        case SAVEBUF_LINE:
            strcpy( *data, tmp->u.data );
            break;
        case SAVEBUF_FCBS:
            **data = '\0';
            for( cfcb = tmp->u.fcbs.head; cfcb != NULL; cfcb = cfcb->next ) {
                FetchFcb( cfcb );
                for( cline = cfcb->lines.head; cline != NULL; cline = cline->next ) {
                    strcat( *data, cline->data );
                    strcat( *data, "\\n" );
                }
            }
            break;
        }
    }
#ifdef __WIN__
    if( tmp == &clip ) {
        freeSavebuf( &clip );
    }
#endif
    return( rc );

} /* GetSavebufString */
Exemplo n.º 13
0
/*
 * SplitFcbAtLine - split a fcb at specified line (specified line goes in
 *                  new one) - line 1 causes new fcb to be created at start
 */
vi_rc SplitFcbAtLine( linenum lne, file *f, fcb *fb )
{
    linenum     sline;
    int         bytecnt = 0;
    line        *cl, *pl;
    fcb         *cfcb;

    /*
     * if at start line or end line + 1, no splitting possible
     */
    if( lne == fb->start_line ) {
        return( NO_SPLIT_CREATED_AT_START_LINE );
    }
    if( lne == fb->end_line + 1 ) {
        return( NO_SPLIT_CREATED_AT_END_LINE );
    }

    /*
     * check if we tried to split at line that is not in fcb;
     */
    if( lne > fb->end_line ) {
        return( ERR_NO_SUCH_LINE );
    }

    /*
     * get fcb to split, and make sure that it isn't swapped while
     * we use it
     */
    FetchFcb( fb );
    fb->non_swappable = TRUE;

    /*
     * get position
     */
    cl = fb->lines.head;
    for( sline = fb->start_line; sline != lne; sline++ ) {
        bytecnt += cl->len + 1;
        cl = cl->next;
    }

    /*
     * add the new fcb
     */
    pl = cl->prev;
    cfcb = FcbAlloc( f );
    InsertLLItemAfter( (ss **)&(f->fcbs.tail), (ss *)fb, (ss *)cfcb );

    /*
     * reset line data for new fcb
     */
    cfcb->start_line = lne;
    cfcb->end_line = fb->end_line;
    cfcb->lines.head = cl;
    cfcb->lines.head->prev = NULL;
    cfcb->lines.tail = fb->lines.tail;
    cfcb->byte_cnt = fb->byte_cnt - bytecnt;

    /*
     * reset line data for original fcb
     */
    fb->end_line = lne - 1;
    fb->lines.tail = pl;
    fb->lines.tail->next = NULL;
    fb->byte_cnt = bytecnt;

    /*
     * check for locked fcb
     */
    if( fb->globalmatch ) {
        /*
         * make sure original one should stay locked
         */
        fb->globalmatch = FALSE;
        for( cl = fb->lines.head; cl != NULL; cl = cl->next ) {
            if( cl->inf.ld.globmatch ) {
                fb->globalmatch = TRUE;
                break;
            }
        }
        /*
         * see if new one needs to be locked
         */
        for( cl = cfcb->lines.head; cl != NULL; cl = cl->next ) {
            if( cl->inf.ld.globmatch ) {
                cfcb->globalmatch = TRUE;
                break;
            }
        }
    }

    /*
     * release fcbs
     */
    fb->non_swappable = FALSE;
    cfcb->non_swappable = FALSE;
    return( ERR_NO_ERR );

} /* SplitFcbAtLine */
Exemplo n.º 14
0
/*
 * Global - perform global command
 */
vi_rc Global( linenum n1, linenum n2, const char *data, int dmt )
{
    char        *sstr, *linedata;
    bool        match;
    vi_rc       rc;
    vi_rc       rc1;
    long        changecnt = 0;
    linenum     ll;
    fcb         *cfcb;
    line        *cline;
    regexp      crx;
    i_mark      pos;

    /*
     * get search string and command
     */
    rc = ModificationTest();
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }
    sstr = alloca( MAX_INPUT_LINE );
    if( sstr == NULL ) {
        return( ERR_NO_STACK );
    }
    data = SkipLeadingSpaces( data );
    data = GetNextWord( data, sstr, SingleSlash );
    if( *sstr == '\0' ) {
        return( ERR_INVALID_GLOBAL_CMD );
    }
    if( *data == '/' )
    	++data;     // skip one slash character
    data = SkipLeadingSpaces( data );

    /*
     * verify last line
     */
    if( n2 > CurrentFile->fcbs.tail->end_line ) {
        rc = CFindLastLine( &ll );
        if( rc != ERR_NO_ERR ) {
            return( rc );
        }
        if( n2 > ll ) {
            return( ERR_INVALID_LINE_RANGE );
        }
    }

    /*
     * set for start of search
     */
    if( EditFlags.Verbose && EditFlags.EchoOn ) {
        ClearWindow( MessageWindow );
    }
    rc = CurrentRegComp( sstr );
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }
    SaveCurrentFilePos();
    StartUndoGroup( UndoStack );
    EditFlags.DisplayHold = true;

    /*
     * pass one - find all matches
     */
    for( pos.line = n1; pos.line <= n2; pos.line++ ) {

        /*
         * go thorugh file, marking global lines
         */
        pos.column = 0;
        rc = FindRegularExpression( NULL, &pos, &linedata, n2, 0 );
        if( rc != ERR_NO_ERR ) {
            if( rc == ERR_FIND_PAST_TERM_LINE || rc == ERR_FIND_NOT_FOUND ||
                rc == ERR_FIND_END_OF_FILE ) {
                break;
            }
            RestoreCurrentFilePos();
            EditFlags.DisplayHold = false;
            return( rc );
        }
        if( pos.line > n2 ) {
            break;
        }

        /*
         * go to appropriate spot in file
         */
        rc = GoToLineNoRelCurs( pos.line );
        if( rc != ERR_NO_ERR ) {
            RestoreCurrentFilePos();
            EditFlags.DisplayHold = false;
            return( rc );
        }

        /*
         * mark fcb and line for a match
         */
        CurrentFcb->globalmatch = true;
        CurrentLine->u.ld.globmatch = true;
        if( EditFlags.Verbose && EditFlags.EchoOn ) {
            // WPrintfLine( MessageWindow,1,"Match on line %l",clineno );
            Message1( "Match on line %l", pos.line );
        }
    }


    /*
     * negate range, if needed
     */
    if( dmt ) {
        /*
         * run through each line, flipping globmatch flag on lines
         */
        CGimmeLinePtr( n1, &CurrentFcb, &CurrentLine );
        match = false;
        for( CurrentPos.line = n1; CurrentPos.line <= n2; CurrentPos.line++ ) {
            if( CurrentLine->u.ld.globmatch ) {
                CurrentLine->u.ld.globmatch = false;
            } else {
                match = true;
                CurrentLine->u.ld.globmatch = true;
            }
            CurrentLine = CurrentLine->next;
            if( CurrentLine == NULL ) {
                CurrentFcb->globalmatch = match;
                CurrentFcb = CurrentFcb->next;
                FetchFcb( CurrentFcb );
                CurrentLine = CurrentFcb->lines.head;
                match = false;
            }
        }
    }

    /*
     * Pass 2: do all changes
     */
    rc = ERR_NO_ERR;
    EditFlags.GlobalInProgress = true;
    memcpy( &crx, CurrentRegularExpression, sizeof( crx ) );

    for( CurrentFcb = CurrentFile->fcbs.head; CurrentFcb != NULL; CurrentFcb = CurrentFcb->next ) {
        if( !CurrentFcb->globalmatch )
            continue;
        FetchFcb( CurrentFcb );
        CurrentPos.line = CurrentFcb->start_line;
        for( CurrentLine = CurrentFcb->lines.head; CurrentLine != NULL; CurrentLine = CurrentLine->next, CurrentPos.line++ ) {
            if( !CurrentLine->u.ld.globmatch )
                continue;
            CurrentLine->u.ld.globmatch = false;
            changecnt++;

            CurrentPos.column = 1;
            ProcessingMessage( CurrentPos.line );
            /*
            * build command line
            */
            rc = RunCommandLine( data );
            if( rc > ERR_NO_ERR ) {
                break;
            }
        }
        if( rc > ERR_NO_ERR ) {
            break;
        }
        CurrentFcb->globalmatch = false;
    }

    /*
     * we have an error, so fix up fcbs
     */
    if( rc > ERR_NO_ERR ) {
        for( cfcb = CurrentFile->fcbs.head; cfcb != NULL; cfcb = cfcb->next ) {
            if( cfcb->globalmatch ) {
                cfcb->globalmatch = false;
                cfcb->non_swappable = false;
                for( cline = cfcb->lines.head; cline != NULL; cline = cline->next ) {
                    cline->u.ld.globmatch = false;
                }
            }
        }
    }

    /*
     * display results
     */
    EditFlags.GlobalInProgress = false;
    EditFlags.DisplayHold = false;
    EndUndoGroup( UndoStack );
    RestoreCurrentFilePos();
    rc1 = SetCurrentLine( CurrentPos.line );
    if( rc1 != ERR_NO_ERR ) {
        if( rc1 == ERR_NO_SUCH_LINE ) {
            SetCurrentLine( 1 );
        } else {
            return( rc1 );
        }
    }
    Message1( "%l matches found",changecnt );
    DCDisplayAllLines();
    return( rc );

} /* Global */
Exemplo n.º 15
0
/*
 * DoGenericFilter - filter some crap
 */
vi_rc DoGenericFilter( linenum s, linenum e, const char *cmd )
{
    fcb         *cfcb, *tfcb;
    line        *cline;
    vi_rc       rc;
    char        filtin[_MAX_PATH], filtout[_MAX_PATH];
    fcb_list    fcblist;
    int         fh;

    rc = ModificationTest();
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }

    /*
     * filter on a line
     */
    rc = GetCopyOfLineRange( s, e, &fcblist );
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }

    /*
     * get file
     */
    MakeTmpPath( filtin, FILTER_FILE_NAME );
    fh = mkstemp( filtin );
    if( fh == -1 )
        return( ERR_FILE_OPEN );

    /*
     * now, dump this crap to a tmp file
     */
    for( cfcb = fcblist.head; cfcb != NULL; cfcb = tfcb ) {
        FetchFcb( cfcb );
        for( cline = cfcb->lines.head; cline != NULL; cline = cline->next ) {
            write( fh, cline->data, strlen( cline->data ) );
#if defined( __UNIX__ )
            write( fh, "\n", 1 );
#else
            write( fh, "\r\n", 2 );
#endif
        }
        tfcb = cfcb->next;
        FcbFree( cfcb );
    }
    close( fh );

    MakeTmpPath( filtout, FILTER_FILE_NAME );
    fh = mkstemp( filtout );
    if( fh == -1 ) {
        remove( filtin );
        return( ERR_FILE_OPEN );
    }
    close( fh );
    /*
     * shell out to the given command
     */
    ExecCmd( filtin, filtout, cmd );
    StartUndoGroup( UndoStack );
    rc = DeleteLineRange( s, e, 0 );
    if( rc == ERR_NO_ERR ) {
        ReadAFile( s - 1, filtout );
        Message1( "%l lines filtered through %s", e - s + 1, cmd );
    }
    EndUndoGroup( UndoStack );

    /*
     * cleanup
     */
    if( rc == ERR_NO_ERR ) {
        rc = DO_NOT_CLEAR_MESSAGE_WINDOW;
    }
    remove( filtin );
    remove( filtout );
    return( rc );

} /* DoGenericFilter */
Exemplo n.º 16
0
/*
 * InsertLinesAtCursor - insert a set of lines at current pos. in file
 */
vi_rc InsertLinesAtCursor( fcb_list *fcblist, undo_stack *us )
{
    fcb         *cfcb;
    linenum     e;
    int         lastLineLen;
    char        *source;
    line        *tLine;
    vi_rc       rc;

    rc = ModificationTest();
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }

    /*
     * 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);
    }

    // add chars from right of cursor to end of last line of buffer
    source = CurrentLine->data + CurrentPos.column - 1;
    lastLineLen = fcblist->tail->lines.tail->len;
    fcblist->tail->lines.tail->len += CurrentLine->len - CurrentPos.column + 1;

    fcblist->tail->byte_cnt += CurrentLine->len - CurrentPos.column + 1;

    tLine = fcblist->tail->lines.tail->prev;
    fcblist->tail->lines.tail = MemReAlloc( fcblist->tail->lines.tail,
                    sizeof( line ) + fcblist->tail->lines.tail->len + 1 );
    if( tLine ) {
        tLine->next = fcblist->tail->lines.tail;
    }
    strcpy( fcblist->tail->lines.tail->data + lastLineLen, source );

    StartUndoGroup( us );

    // create new current line in work line
    CurrentLineReplaceUndoStart();
    GetCurrentLine();
    WorkLine->len = CurrentPos.column + fcblist->head->lines.head->len - 1;
    strcpy( WorkLine->data + CurrentPos.column - 1, fcblist->head->lines.head->data );

    // replace current line
    ReplaceCurrentLine();
    CurrentLineReplaceUndoEnd( true );

    // remove first line of buffer
    FetchFcb( fcblist->head );
    fcblist->head->non_swappable = true;
    fcblist->head->start_line++;
    fcblist->head->byte_cnt -= fcblist->head->lines.head->len + 1;
    tLine = fcblist->head->lines.head;
    fcblist->head->lines.head = fcblist->head->lines.head->next;
    fcblist->head->lines.head->prev = NULL;
    MemFree( tLine );
    fcblist->head->non_swappable = false;

    // add rest of lines of buffer & done
    if( fcblist->head->lines.head) {
        InsertLines( CurrentPos.line, fcblist, us );
    }
    EndUndoGroup( us );

    // if are indeed linebased, move cursor as well
    if( !EditFlags.LineBased ) {
        GoToLineNoRelCurs( CurrentPos.line + e - 1 );
        GoToColumnOnCurrentLine( lastLineLen + 1 );
    }

    return( ERR_NO_ERR );

} /* InsertLinesAtCursor */
Exemplo n.º 17
0
/*
 * AddFcbsToClipboard - add all lines in a given set of fcbs to the clipboard
 */
int AddFcbsToClipboard( fcb_list *fcblist )
{
    fcb                 *cfcb;
    line                *cline;
    char                _HUGE_ *ptr;
    long                size;
    int                 i;
    GLOBALHANDLE        hglob;
    bool                crlf_left_to_write = false;

    if( !openClipboardForWrite() ) {
        return( ERR_CLIPBOARD );
    }

    /*
     * compute the number of bytes in total
     */
    size = 1;   // for trailing null char
    for( cfcb = fcblist->head; cfcb != NULL; cfcb = cfcb->next ) {
        size += (long)cfcb->byte_cnt +
                (long)(cfcb->end_line-cfcb->start_line + 1);
        if( cfcb == fcblist->tail ) {
            break;
        }
    }

    /*
     * get the memory to store this stuff
     */
    hglob = GlobalAlloc( GMEM_MOVEABLE, size );
    if( hglob == NULL ) {
        CloseClipboard();
        return( ERR_CLIPBOARD );
    }

    ptr = GetPtrGlobalLock( hglob );
    if( ptr == NULL ) {
        CloseClipboard();
        return( ERR_CLIPBOARD );
    }

    /*
     * copy all lines into this pointer
     */
    for( cfcb = fcblist->head; cfcb != NULL; cfcb = cfcb->next ) {
        FetchFcb( cfcb );
        for( cline = cfcb->lines.head; cline != NULL; cline = cline->next ) {
            // one CR,LF left to write?
            if( crlf_left_to_write ) {
                // yes: write it
                crlf_left_to_write = false;
                *ptr = CR;
                INC_POINTER( ptr );
                *ptr = LF;
                INC_POINTER( ptr );
            }
            for( i = 0; i < cline->len; i++ ) {
                *ptr = cline->data[i];
                INC_POINTER( ptr );
            }
            // remember to write one CR,LF next time
            crlf_left_to_write = true;
        }
        if( cfcb == fcblist->tail ) {
            break;
        }
    }
    // the last CR,LF is omitted
    *ptr = 0;
    GlobalUnlock( hglob );
    SetClipboardData( CF_TEXT, hglob );
    CloseClipboard();
    return( ERR_NO_ERR );

} /* AddFcbsToClipboard */
Exemplo n.º 18
0
/*
 * CurrentLineReplaceUndoEnd - actually add the undo
 */
void CurrentLineReplaceUndoEnd( int endgrp )
{
    fcb         *cfcb, *nfcb;
    undo        *top, *delrec;
    fcb_list    fcblist;

    if( !EditFlags.Undo || UndoStack == NULL ) {
        return;
    }
    /*
     * see if we can merge this with the last undo record
     * (provided we are in an open undo group)
     *
     * we need the following undo sequence:
     * END_UNDO_GROUP
     * UNDO_INSERT_LINES
     *      - must have end line one less than the current line
     * UNDO_DELETE_FCBS
     *      - must have last line to insert being two less
     *        than the current (since then the undo for
     *        the current would be on the line ONE less than
     *        the current);
     */
    if( endgrp && UndoStack->OpenUndo > 0 ) {
        top = UndoStack->stack[UndoStack->current];
        if( top != NULL && top->type == END_UNDO_GROUP ) {
            top = top->next;
            if( top != NULL && top->type == UNDO_INSERT_LINES ) {
                if( top->data.del_range.end == CurrentPos.line - 1 ) {
                    delrec = top;
                    top = top->next;
                    if( top != NULL && top->type == UNDO_DELETE_FCBS ) {
                        cfcb = top->data.fcbs.tail;
                        if( cfcb->end_line == CurrentPos.line - 2 ) {
                            /*
                             * FINALLY, we can add it. either
                             * add to current fcb or add a new
                             * fcb
                             */
                            if( (FcbSize( cfcb ) + lineSave->len + 4) <=
                                MAX_IO_BUFFER ) {
                                FetchFcb( cfcb );
                                InsertLLItemAfter( (ss **)&cfcb->lines.tail,
                                    (ss *)cfcb->lines.tail, (ss *)lineSave );
                                cfcb->byte_cnt += lineSave->len + 1;
                                cfcb->end_line++;
                            } else {
                                nfcb = singleLineFcb();
                                nfcb->start_line = nfcb->end_line = cfcb->end_line + 1;
                                InsertLLItemAfter( (ss **)&(top->data.fcbs.tail),
                                    (ss *)cfcb, (ss *)nfcb );
                                nfcb->non_swappable = FALSE;
                            }
                            delrec->data.del_range.end++;
                            Modified( TRUE );
                            return;

                        }
                    }
                }
            }
        }
    }

    /*
     * create an fcb with a single line
     */
    cfcb = singleLineFcb();

    /*
     * build undo action
     */
    fcblist.head = cfcb;
    fcblist.tail = cfcb;
    StartUndoGroupWithPosition( UndoStack, cLine, pageTop, cCol );
    UndoDeleteFcbs( CurrentPos.line - 1, &fcblist, UndoStack );
    UndoInsert( CurrentPos.line, CurrentPos.line, UndoStack );
    if( endgrp ) {
        EndUndoGroup( UndoStack );
    }
    Modified( TRUE );
    cfcb->non_swappable = FALSE;

} /* CurrentLineReplaceUndoEnd */