clglob.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 304 行

C
304
字号
/****************************************************************************
*
*                            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:  Global commands execution.
*
****************************************************************************/


#include <stdio.h>
#include <string.h>
#include "walloca.h"
#include "vi.h"
#include "rxsupp.h"
#include "win.h"

/*
 * Global - perform global command
 */
int Global( linenum n1, linenum n2, char *data, int dmt )
{
    char        *sstr,*cmd,*linedata;
    int         i,todo;
    int         ccol,rc;
    long        changecnt=0;
    linenum     clineno,llineno,ll;
    fcb         *cfcb;
    line        *cline;
    regexp      crx;

    /*
     * get search string and command
     */
    if( rc = ModificationTest() ) {
        return( rc );
    }
    sstr = alloca( MAX_INPUT_LINE );
    cmd = alloca( MAX_INPUT_LINE );
    if( cmd == NULL || sstr == NULL ) {
        return( ERR_NO_STACK );
    }
    RemoveLeadingSpaces( data );
    if( NextWordSlash( data, sstr ) < 0 ) {
        return( ERR_INVALID_GLOBAL_CMD );
    }
    RemoveLeadingSpaces( data );
    EliminateFirstN( data,1 );

    /*
     * verify last line
     */
    if( n2 > CurrentFile->fcb_tail->end_line ) {
        i = CFindLastLine( &ll );
        if( i ) {
            return( i );
        }
        if( n2 > ll ) {
            return( ERR_INVALID_LINE_RANGE );
        }
    }

    /*
     * set for start of search
     */
    if( EditFlags.Verbose && EditFlags.EchoOn ) {
        ClearWindow( MessageWindow );
    }
    i = CurrentRegComp( sstr );
    if( i ) {
        return( i );
    }
    SaveCurrentFilePos();
    llineno = n1-1;
    clineno = n1;
    ccol = 0;
    StartUndoGroup( UndoStack );
    EditFlags.DisplayHold = TRUE;
    strcpy( sstr, data );

    /*
     * pass one - find all matches
     */
    while( TRUE ) {

        /*
         * go thorugh file, marking global lines
         */
        i = FindRegularExpression( NULL, &clineno, ccol, &linedata, n2, FALSE );
        if( !i ) {
            ccol = GetCurrRegExpColumn( linedata );
        } else {
            if( i == ERR_FIND_PAST_TERM_LINE || i == ERR_FIND_NOT_FOUND || i == ERR_FIND_END_OF_FILE )  {
                break;
            }
            RestoreCurrentFilePos();
            EditFlags.DisplayHold = FALSE;
            return( i );
        }
        if( clineno > n2 ) {
            break;
        }

        /*
         * go to appropriate spot in file
         */
        i = GoToLineNoRelCurs( clineno );
        if( i ) {
            RestoreCurrentFilePos();
            EditFlags.DisplayHold = FALSE;
            return( i );
        }

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

        clineno++;
        if( clineno > n2 ) {
            break;
        }
        ccol = 0;

    }


    /*
     * negate range, if needed
     */
    if( dmt ) {
        /*
         * run through each line, flipping globmatch flag on lines
         */
        CGimmeLinePtr( n1, &CurrentFcb, &CurrentLine );
        CurrentLineNumber = n1;
        while( TRUE ) {
            i = FALSE;
            while( CurrentLine != NULL && CurrentLineNumber <= n2 ) {
                if( CurrentLine->inf.ld.globmatch ) {
                    CurrentLine->inf.ld.globmatch = FALSE;
                } else {
                    i = TRUE;
                    CurrentLine->inf.ld.globmatch = TRUE;
                }
                CurrentLine = CurrentLine->next;
                CurrentLineNumber++;
            }
            CurrentFcb->globalmatch = i;
            if( CurrentLineNumber > n2 ) {
                break;
            }
            CurrentFcb = CurrentFcb->next;
            FetchFcb( CurrentFcb );
            CurrentLine = CurrentFcb->line_head;
        }

    }

    /*
     * Pass 2: do all changes
     */
    EditFlags.GlobalInProgress = TRUE;
    memcpy( &crx, CurrentRegularExpression, sizeof( crx ) );
    while( TRUE ) {

        /*
         * get fcb with a change to do
         */
        todo = FALSE;
        CurrentFcb = CurrentFile->fcb_head;
        while( CurrentFcb != NULL ) {

            if( CurrentFcb->globalmatch ) {

                /*
                 * find a line
                 */
                FetchFcb( CurrentFcb );
                CurrentLineNumber = CurrentFcb->start_line;
                CurrentLine = CurrentFcb->line_head;
                while( CurrentLine != NULL ) {
                    if( CurrentLine->inf.ld.globmatch ) {
                        todo = TRUE;
                        break;
                    }
                    CurrentLineNumber++;
                    CurrentLine = CurrentLine->next;
                }

                if( !todo ) {
                    CurrentFcb->globalmatch = FALSE;
                }
                else break;

            }
            CurrentFcb = CurrentFcb->next;

        }

        if( !todo ) {
            break;
        }

        /*
         * reset info
         */
        CurrentLine->inf.ld.globmatch = FALSE;
        cfcb = CurrentFcb;
        CurrentColumn = 1;

        /*
         * build command line
         */
        changecnt++;
        strcpy( cmd, sstr );
        ProcessingMessage( CurrentLineNumber );

        rc = RunCommandLine( cmd );
        if( rc > 0 ) {
            break;
        }

    }

    /*
     * we have an error, so fix up fcbs
     */
    if( rc > 0 ) {

        cfcb = CurrentFile->fcb_head;
        while( cfcb != NULL ) {
            if( cfcb->globalmatch ) {
                cfcb->globalmatch = FALSE;
                cfcb->non_swappable = FALSE;
                cline = cfcb->line_head;
                while( cline != NULL ) {
                    cline->inf.ld.globmatch = FALSE;
                    cline = cline->next;
                }
            }
            cfcb = cfcb->next;
        }

    }

    /*
     * display results
     */
    EditFlags.GlobalInProgress = FALSE;
    EditFlags.DisplayHold = FALSE;
    EndUndoGroup( UndoStack );
    RestoreCurrentFilePos();
    i = SetCurrentLine( CurrentLineNumber );
    if( i ) {
        if( i == ERR_NO_SUCH_LINE ) {
            SetCurrentLine( 1 );
        } else {
            return( i );
        }
    }
    Message1( "%l matches found",changecnt );
    DCDisplayAllLines();
    return( rc );

} /* Global */

/*
 * ProcessingMessage - display what line is being processed
 */
void ProcessingMessage( linenum cln )
{
    if( EditFlags.Verbose && EditFlags.EchoOn ) {
        // WPrintfLine( MessageWindow,1,"Processing line %l",cln );
        Message1( "Processing line %l", cln );
    }
} /* ProcessingMessage */

⌨️ 快捷键说明

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