savebuf.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 643 行 · 第 1/2 页

C
643
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <stdio.h>
#include <string.h>
#include "vi.h"
#include "keys.h"

#ifdef __WIN__
extern int AddLineToClipboard( char *data, int scol, int ecol );
extern int AddFcbsToClipboard( fcb *head, fcb *tail );
extern int GetClipboardSavebuf( savebuf *clip );
extern bool IsClipboardEmpty( void );
#endif

/*
 * freeSavebuf - release savebuf data
 */
static void freeSavebuf( savebuf *tmp )
{
    fcb *cfcb,*tfcb;

    switch( tmp->type ) {
    case SAVEBUF_NOP:
        break;
    case SAVEBUF_LINE:
        MemFree( tmp->first.data );
        break;
    case SAVEBUF_FCBS:
        cfcb = tmp->first.fcb_head;
        while( cfcb != NULL ) {
            tfcb = cfcb->next;
            FreeEntireFcb( cfcb );
            cfcb = tfcb;
        }
        break;
    }

} /* freeSavebuf */

/*
 * rotateSavebufs - rotate save buffers forward, disposing of last
 */
static void rotateSavebufs( int start )
{
    int i;

    freeSavebuf( &Savebufs[ MAX_SAVEBUFS-1 ] );

    /*
     * now, rotate the buffers forward
     */
    for( i=MAX_SAVEBUFS-1; i > start ;i-- ) {
        memcpy( &(Savebufs[i]),&(Savebufs[i-1]), SAVEBUF_SIZE );
    }

} /* rotateSavebufs */

/*
 * insertGenericSavebuf - insert contents of a savebuf before/after current pos
 */
static int insertGenericSavebuf( int buf, int afterflag )
{
#ifdef __WIN__
    savebuf     clip;
#endif
    savebuf     *tmp;
    fcb         *head=NULL,*tail=NULL,*end;
    int         rc,i,scol,len;
    int         maxCursor;

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

    if( EditFlags.Modeless ) {
        DeleteSelectedRegion();
        SelRgn.selected = FALSE;
    }

#ifdef __WIN__
    if( buf == CLIPBOARD_SAVEBUF ) {
        rc = GetClipboardSavebuf( &clip );
        if( rc ) {
            return( rc );
        }
        tmp = &clip;
    } else
#endif
    if( buf >= MAX_SAVEBUFS ) {
        tmp = &SpecialSavebufs[buf-MAX_SAVEBUFS];
    } else {
        tmp = &Savebufs[buf];
    }
    switch( tmp->type ) {
    case SAVEBUF_NOP:
        rc = ERR_EMPTY_SAVEBUF;
        break;
    case SAVEBUF_LINE:
        /*
         * get starting data
         */
        len = strlen( tmp->first.data );
        if( len + CurrentLine->len >= MaxLine ) {
            rc = ERR_LINE_FULL;
            break;
        }
        if( afterflag ) {
            scol = CurrentColumn;
        } else {
            scol = CurrentColumn-1;
        }
        CurrentLineReplaceUndoStart();
        GetCurrentLine();

        /*
         * open up line and copy in data
         */
        if( WorkLine->len == 0 ) {
            scol = 0;
        }
        for( i=WorkLine->len;i>=scol;i-- ) {
            WorkLine->data[i+len] = WorkLine->data[i];
        }
        for( i=0;i<len;i++ ) {
            WorkLine->data[i+scol] = tmp->first.data[i];
        }
        WorkLine->len += len;
        DisplayWorkLine( TRUE );
        ReplaceCurrentLine();
        CurrentLineReplaceUndoEnd( TRUE );
        scol += len + 1;

        maxCursor = CurrentLine->len;
        if( EditFlags.Modeless ) {
            maxCursor++;
        }
        if( scol > maxCursor ) {
            scol = maxCursor;
        }
        rc = GoToColumn( scol, maxCursor );
        break;

    case SAVEBUF_FCBS:
        end = tmp->fcb_tail->next;
        tmp->fcb_tail->next = NULL;
        CreateDuplicateFcbList( tmp->first.fcb_head, &head, &tail );
        tmp->fcb_tail->next = end;

        if( !EditFlags.LineBased ) {
            rc = InsertLinesAtCursor( head, tail, UndoStack );
        } else {
            if( afterflag) {
                rc = InsertLines( CurrentLineNumber, head, tail, UndoStack );
            } else {
                rc = InsertLines( CurrentLineNumber-1, head, tail, UndoStack );
            }
        }
        break;
    }
#ifdef __WIN__
    if( tmp == &clip ) {
        freeSavebuf( &clip );
    }
#endif

    EditFlags.Dotable = TRUE;

    return( rc );

} /* insertGenericSavebuf */

/*
 * InsertSavebufBefore - insert contents of current savebuf before current pos
 */
int InsertSavebufBefore( void )
{
    if( SavebufNumber == NO_SAVEBUF ) {
        return( insertGenericSavebuf( CurrentSavebuf, FALSE ) );
    } else {
        return( insertGenericSavebuf( SavebufNumber, FALSE ) );
    }

} /* InsertSavebufBefore */

/*
 * InsertSavebufBefore2 - alternate insert savebuf (cuz of windows)
 */
int InsertSavebufBefore2( void )
{
    if( SavebufNumber == NO_SAVEBUF ) {
        #ifdef __WIN__
            return( insertGenericSavebuf( CLIPBOARD_SAVEBUF, FALSE ) );
        #else
            return( insertGenericSavebuf( CurrentSavebuf, FALSE ) );
        #endif
    } else {
        return( insertGenericSavebuf( SavebufNumber, FALSE ) );
    }

} /* InsertSavebufBefore2 */

/*
 * InsertSavebufAfter - insert contents of current savebuf after current pos
 */
int InsertSavebufAfter( void )
{
    if( SavebufNumber == NO_SAVEBUF ) {
        return( insertGenericSavebuf( CurrentSavebuf, TRUE  ) );
    } else {
        return( insertGenericSavebuf( SavebufNumber, TRUE  ) );
    }

} /* InsertSavebufAfter */

/*
 * InsertSavebufAfter2 - alternate insert savebuf (cuz of windows)
 */
int InsertSavebufAfter2( void )
{
    if( SavebufNumber == NO_SAVEBUF ) {
        #ifdef __WIN__
            return( insertGenericSavebuf( CLIPBOARD_SAVEBUF, TRUE ) );
        #else
            return( insertGenericSavebuf( CurrentSavebuf, TRUE ) );
        #endif
    } else {
        return( insertGenericSavebuf( SavebufNumber, TRUE ) );
    }

} /* InsertSavebufAfter2 */

/*
 * GetSavebufString - get a string made up of stuff in a savebuf
 */
int GetSavebufString( char **data )
{
#ifdef __WIN__
    savebuf     clip;
#endif
    savebuf     *tmp;
    fcb         *cfcb;
    line        *cline;
    int         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 ) {
            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
     */
    switch( tmp->type ) {
    case SAVEBUF_NOP:
        return( ERR_EMPTY_SAVEBUF );
    case SAVEBUF_LINE:
        len = strlen( tmp->first.data );
        break;
    case SAVEBUF_FCBS:
        cfcb = tmp->first.fcb_head;
        len = 0L;
        while( cfcb != NULL ) {
            len += FcbSize( cfcb );
            cfcb = cfcb->next;
        }
        break;
    }
    rc = ERR_NO_ERR;
    if( len > MAX_STR*4 ) {
        rc = ERR_SAVEBUF_TOO_BIG;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?