コード例 #1
0
ファイル: clsubs.c プロジェクト: ABratovic/open-watcom-v2
/*
 * Substitute - perform substitution
 */
vi_rc Substitute( linenum n1, linenum n2, char *data )
{
    char        *sstr, *rstr, *newr;
    char        flag[20], *linedata;
    bool        iflag = false;
    bool        gflag = false;
    bool        undoflag = false;
    bool        restline = false;
    bool        splitpending = false;
    bool        undoline = false;
    int         i, rlen, slen;
    bool        splitme;
    long        changecnt = 0, linecnt = 0;
    linenum     llineno, ll, lastline = 0, extra;
    i_mark      pos;
    vi_rc       rc;

    LastSubstituteCancelled = 0;
    LastChangeCount = 0;
    LastLineCount = 0;

    sstr = alloca( MAX_INPUT_LINE );
    if( sstr == NULL ) {
        return( ERR_NO_STACK );
    }
    strcpy( sstr, data );
    rc = ModificationTest();
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }
    strcpy( data, sstr );
    rstr = alloca( MAX_INPUT_LINE  );
    if( rstr == NULL ) {
        return( ERR_NO_STACK );
    }
    if( NextWordSlash( data, sstr ) < 0 ) {
        return( ERR_INVALID_SUBS_CMD );
    }
    if( NextWordSlash( data, rstr ) < 0 ) {
        return( ERR_INVALID_SUBS_CMD );
    }
    slen = NextWord1( data, flag );
    for( i = 0; i < slen; i++ ) {
        switch( flag[i] ) {
        case 'g':
            gflag = true;
            break;
        case 'i':
        case 'c':
            iflag = true;
            break;
        }
    }
    rc = CurrentRegComp( sstr );
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }

    /*
     * 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 );
    }
    SaveCurrentFilePos();
    llineno = n1 - 1;

    EditFlags.AllowRegSubNewline = true;
    newr = StaticAlloc();
    for( pos.column = 0, pos.line = n1;
        pos.line <= n2;
        nextSearchStartPos( &pos, gflag, rlen ) ) {

        /*
         * get regular expression, and build replacement string
         */
        rc = FindRegularExpression( NULL, &pos, &linedata, n2, 0 );
        if( rc != ERR_NO_ERR || pos.line > n2 ) {
            break;
        }

        slen = GetCurrRegExpLength();
        splitme = RegSub( CurrentRegularExpression, rstr, newr, pos.line );
        rlen = strlen( newr );

        ProcessingMessage( pos.line );

        /*
         * if in global mode, see if we already have an undo for
         * this line
         */
        if( gflag ) {
            if( lastline != pos.line ) {
                undoline = false;
            }
        }

        /*
         * interactive mode? yes, then display text and ask to change
         */
        if( iflag ) {
            change_resp rsp;

            if( !restline ) {
                ClearWindow( MessageWindow );
            }
            restline = true;
            GoToLineNoRelCurs( pos.line );
            if( EditFlags.GlobalInProgress ) {
                EditFlags.DisplayHold = false;
                DCDisplayAllLines();
                EditFlags.DisplayHold = true;
            }
            HilightSearchString( &pos, slen );
            rsp = ChangePrompt();
            if( rsp == CHANGE_NO ) {
                ResetDisplayLine();
                rlen = 1;
                continue;
            } else if( rsp == CHANGE_CANCEL ) {
                ResetDisplayLine();
                LastSubstituteCancelled = 1;
                break;
            } else if( rsp == CHANGE_ALL ) {
                ResetDisplayLine();
                iflag = false;
            }
        }

        /*
         * set up for global undo if we haven't already
         */
        if( !undoflag ) {
            StartUndoGroup( UndoStack );
            undoflag = true;
        }

        /*
         * bump change counts
         */
        changecnt++;
        if( llineno != pos.line ) {
            if( splitpending ) {
                splitpending = false;
                extra = SplitUpLine( llineno );
                n2 += extra;
                pos.line += extra;
            }
            linecnt++;
            llineno = pos.line;
        }

        /*
         * get copy of line, and verify that new stuff fits
         */
        CurrentPos.line = pos.line;
        rc = CGimmeLinePtr( pos.line, &CurrentFcb, &CurrentLine );
        if( rc != ERR_NO_ERR ) {
            break;
        }
        if( CurrentLine->len + rlen - slen >= EditVars.MaxLine ) {
            rc = ERR_LINE_FULL;
            break;
        }

        /*
         * now build the individual undo
         */
        CurrentFcb->non_swappable = true;
        if( !undoline ) {
            CurrentLineReplaceUndoStart();
            CurrentLineReplaceUndoEnd( true );
            if( gflag ) {
                undoline = true;
                lastline = pos.line;
            }
        }

        /*
         * remove the old string
         */
        GetCurrentLine();
        WorkLine->len = ReplaceSubString( WorkLine->data, WorkLine->len,
                                          pos.column, pos.column + slen - 1, newr, rlen );
        if( iflag ) {
            DisplayWorkLine( true );
        }
        ReplaceCurrentLine();

        /*
         * if not global, only do this change on this line
         */
        if( splitme ) {
            splitpending = true;
        }
        CurrentFcb->non_swappable = false;
    }
    StaticFree( newr );
    EditFlags.AllowRegSubNewline = false;
    /*
    * is there still a split line pending?
    */
    if( splitpending ) {
        SplitUpLine( llineno );
    }
    RestoreCurrentFilePos();
    if( restline ) {
        SetCurrentLine( CurrentPos.line );
        GoToColumnOK( CurrentPos.column );
    }
    if( undoflag ) {
        EndUndoGroup( UndoStack );
    }
    switch( rc ) {
    case ERR_NO_ERR:
    case ERR_LINE_FULL:
    case ERR_FIND_PAST_TERM_LINE:
    case ERR_FIND_NOT_FOUND:
    case ERR_FIND_END_OF_FILE:
        /*
        * display results
        */
        if( rc == ERR_LINE_FULL ) {
            Message1( "Stopped at line %l - line full", pos.line );
        } else {
            Message1( "%l changes on %l lines", changecnt, linecnt );
            LastLineCount = linecnt;
            LastChangeCount = changecnt;
        }
        DCDisplayAllLines();
        rc = ERR_NO_ERR;
        break;
    default:
        break;
    }
    return( rc );

} /* Substitute */
コード例 #2
0
/*
 * FindRegularExpressionBackwards - do a reverse search for a regular expression
 */
vi_rc FindRegularExpressionBackwards( char *pat, i_mark *pos1, char **linedata,
                                      linenum termline, find_type flags )
{
    vi_rc       rc;
    char        *data;
    bool        wrapped = false;
    bool        found;
    linenum     ilineno = 0;
    line        *cline;
    fcb         *cfcb;
    regexp      rcpy;
    int         scol;
    linenum     sline;

    /*
     * initialize for search
     */
    if( wrapMsgPrinted ) {
        wrapMsgPrinted = false;
        ClearWindow( message_window_id );
    }
    sline = pos1->line;
    rc = CGimmeLinePtr( sline, &cfcb, &cline );
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }
    if( flags & FINDFL_WRAP ) {
        ilineno = sline;
    }
    scol = pos1->column;
    if( pat != NULL ) {
        rc = CurrentRegComp( pat );
        if( rc != ERR_NO_ERR ) {
            return( rc );
        }
    }
    memset( &rcpy, 0, sizeof( rcpy ) );

    /*
     * loop until string found
     */
    for( ;; ) {
        data = cline->data;
        found = false;
        /*
         * run through all possible matches on the line, accepting
         * only the last one
         */
        if( scol >= 0 ) {
            while( *data != '\0' && RegExec( CurrentRegularExpression, data, (data == cline->data) ) ) {
                int     col, len;

                if( RegExpError != ERR_NO_ERR ) {
                    return( RegExpError );
                }
                col = GetCurrRegExpColumn( cline->data );
                len = GetCurrRegExpLength();
                if( col + len > scol ) {
                    break;
                }
                found = true;
                memcpy( &rcpy, CurrentRegularExpression, sizeof( regexp ) );
                data = &(cline->data[col + 1]);
            }
            if( found ) {
                break;
            }
        }

        /*
         * get next line
         */
        rc = GimmePrevLinePtr( &cfcb, &cline );
        if( rc == ERR_NO_ERR ) {
            --sline;
        } else if( rc == ERR_NO_MORE_LINES ) {
            if( (flags & FINDFL_WRAP) == 0 ) {
                return( ERR_FIND_TOP_OF_FILE );
            } else {
                Message1( wrapMsg, "top" );
                MyBeep();
                wrapMsgPrinted = true;
            }
            if( wrapped ) {
                return( ERR_FIND_NOT_FOUND );
            }
            rc = CFindLastLine( &sline );
            if( rc != ERR_NO_ERR ) {
                return( rc );
            }
            rc = CGimmeLinePtr( sline, &cfcb, &cline );
            if( rc != ERR_NO_ERR ) {
                return( rc );
            }
            wrapped = true;
        } else {
            return( rc );
        }
        if( sline < termline ) {
            return( ERR_FIND_PAST_TERM_LINE );
        }
        if( wrapped ) {
            if( sline < ilineno ) {
                return( ERR_FIND_NOT_FOUND );
            }
        }
        scol = cline->len;
    }
    *linedata = cline->data;
    memcpy( CurrentRegularExpression, &rcpy, sizeof( regexp ) );
    pos1->column = GetCurrRegExpColumn( cline->data );
    pos1->line = sline;
    return( ERR_NO_ERR );

} /* FindRegularExpressionBackwards */
コード例 #3
0
/*
 * FindRegularExpression - do a forward search for a regular expression
 */
vi_rc FindRegularExpression( char *pat, i_mark *pos1, char **linedata,
                             linenum termline, find_type flags )
{
    vi_rc       rc;
    int         found;
    linenum     ilineno = 0;
    bool        wrapped = false;
    char        *data;
    line        *cline;
    fcb         *cfcb;
    int         scol;
    linenum     sline;

    /*
     * initialize for search
     */
    if( wrapMsgPrinted ) {
        wrapMsgPrinted = false;
        ClearWindow( message_window_id );
    }
    sline = pos1->line;
    if( flags & FINDFL_WRAP ) {
        ilineno = sline;
    }
    rc = CGimmeLinePtr( sline, &cfcb, &cline );
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }
    scol = pos1->column;
    if( pat != NULL ) {
        rc = CurrentRegComp( pat );
        if( rc != ERR_NO_ERR ) {
            return( rc );
        }
    }

    /*
     * loop until string found
     */
    data = &cline->data[scol];
    while( (found = RegExec( CurrentRegularExpression, data, (data == cline->data) )) == 0 ) {
        if( RegExpError != ERR_NO_ERR ) {
            return( RegExpError );
        }
        /*
         * get next line
         */
        rc = CGimmeNextLinePtr( &cfcb, &cline );
        if( rc == ERR_NO_ERR ) {
            ++sline;
        } else if( rc == ERR_NO_MORE_LINES ) {
            if( (flags & FINDFL_WRAP) == 0 ) {
                return( ERR_FIND_END_OF_FILE );
            } else {
                Message1( wrapMsg, "bottom" );
                MyBeep();
                wrapMsgPrinted = true;
            }
            if( wrapped ) {
                return( ERR_FIND_NOT_FOUND );
            }
            sline = 1;
            rc = CGimmeLinePtr( sline, &cfcb, &cline );
            if( rc != ERR_NO_ERR ) {
                return( rc );
            }
            wrapped = true;
        } else {
            return( rc );
        }
        if( sline > termline ) {
            return( ERR_FIND_PAST_TERM_LINE );
        }
        if( wrapped ) {
            if( sline > ilineno ) {
                return( ERR_FIND_NOT_FOUND );
            }
        }
        scol = 0;
        data = cline->data;
    }
    *linedata = cline->data;
    pos1->column = GetCurrRegExpColumn( cline->data );
    pos1->line = sline;
    return( ERR_NO_ERR );

} /* FindRegularExpression */
コード例 #4
0
ファイル: clglob.c プロジェクト: pavanvunnava/open-watcom-v2
/*
 * 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 */