Exemplo n.º 1
0
/*
 * RestoreCurrentFilePos
 */
void RestoreCurrentFilePos( void )
{
    vi_rc   rc;

    CurrentFile = oldFile[stackDepth];
    CurrentPos = oldCurrentPos[stackDepth];
    LeftTopPos = oldLeftTopPos[stackDepth];

    if( CurrentFile != NULL ) {
        rc = CGimmeLinePtr( CurrentPos.line, &CurrentFcb, &CurrentLine );
        if( rc == ERR_NO_SUCH_LINE ) {
            if( CurrentFile->fcbs.tail != NULL ) {
                CurrentPos.line = CurrentFile->fcbs.tail->end_line;
                CGimmeLinePtr( CurrentPos.line, &CurrentFcb, &CurrentLine );
            }
        }
    } else {
        CurrentFcb = NULL;
        CurrentLine = NULL;
    }

    ValidateCurrentColumn();
    VarAddRandC();
    stackDepth--;

} /* RestoreCurrentFilePos */
Exemplo n.º 2
0
/*
 * GetHiddenBreaks
 */
linenum GetHiddenLineBreaks( linenum s, linenum e )
{
    linenum     curr;
    line        *cline;
    fcb         *cfcb;
    int         i;
    linenum     cnt, s1, e1, tmp;

    if( s > e ) {
        tmp = s;
        s = e;
        e = tmp;
    }
    cnt = 0L;
    curr = s;
    while( curr <=e ) {
        i = CGimmeLinePtr( curr, &cfcb, &cline );
        if( i ) {
            break;
        }
        if( cline->u.ld.hidden ) {
            GetHiddenRange( curr, &s1, &e1 );
            curr = e1 + 1;
            cnt++;
        } else {
            curr++;
        }
    }
    return( cnt );

} /* GetHiddenLineBreaks */
Exemplo n.º 3
0
/*
 * SetCurrentLine - reset current line after changes in current file structure
 */
vi_rc SetCurrentLine( linenum lineno )
{
    int         text_lines;
    fcb         *cfcb;
    line        *cline;
    vi_rc       rc;

    if( lineno <= 0 ) {
        lineno = 1;
    }
    rc = CGimmeLinePtr( lineno, &cfcb, &cline );
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }

    CurrentLine = cline;
    CurrentFcb = cfcb;

    text_lines = WindowAuxInfo( current_window_id, WIND_INFO_TEXT_LINES );
    if( lineno < LeftTopPos.line || lineno > (LeftTopPos.line + text_lines - 1) ) {
        LeftTopPos.line = lineno - text_lines / 2;
    }
    if( LeftTopPos.line < 1 ) {
        LeftTopPos.line = 1;
    }

    CheckCurrentColumn();
    SetCurrentLineNumber( lineno );
    UpdateStatusWindow();
    SetWindowCursor();
    DCDisplayAllLines();
    return( ERR_NO_ERR );

} /* SetCurrentLine */
Exemplo n.º 4
0
/*
 * GimmeCurrentWord - fetch word at cursor position
 */
vi_rc GimmeCurrentWord( char *buffer, int buffer_size, bool big )
{
    i_mark      curr, end, start;
    int         i, j;
    line        *line;
    fcb         *fcb;
    vi_rc       rc;

    curr = CurrentPos;
    start = curr;
    rc = MarkEndOfNextWordForward( &end, &curr, big );
    if( rc == ERR_NO_ERR ) {
        rc = CGimmeLinePtr( end.line, &fcb, &line );
        if( rc == ERR_NO_ERR ) {
            i = start.column - 1;
            j = 0;
            buffer_size -= 1;
            while( i < end.column && j < buffer_size ) {
                buffer[j++] = line->data[i++];
            }
            buffer[j] = '\0';
        }
    }
    return( rc );

} /* GimmeCurrentWord */
Exemplo n.º 5
0
/*
 * markRegion - mark a region as selected/unselected
 */
static void markRegion( bool val )
{
    fcb         *cfcb;
    line        *cline;
    linenum     ln;
    linenum     s, e;

    if( SelRgn.start.line > SelRgn.end.line ) {
        s = SelRgn.end.line;
        e = SelRgn.start.line;
    } else {
        s = SelRgn.start.line;
        e = SelRgn.end.line;
    }

    if( CGimmeLinePtr( s, &cfcb, &cline ) ) {
        return;
    }
    ln= e - s;
    for( ;; ) {
        cline->u.ld.hilite = val;
        ln--;
        if( ln < 0 ) {
            break;
        }
        if( CGimmeNextLinePtr( &cfcb, &cline ) ) {
            break;
        }
    }

} /* markRegion */
Exemplo n.º 6
0
/*
 * SetSelectedRegion - set the selected region to a specific area
 */
vi_rc SetSelectedRegion( range *r )
{
    vi_rc   rc;
    line    *line;
    fcb     *fcb;

    UnselectRegion();
    SelRgn.start.line = r->start.line;
    SelRgn.end.line = r->end.line;

    SelRgn.start_col_v = 1;
    if( r->line_based ) {
        SelRgn.lines = TRUE;
        SelRgn.start.column = 1;
        SelRgn.end.column = LineLength( r->end.line );
    } else {
        SelRgn.lines = FALSE;
        if( r->start.column < r->end.column ) {
            SelRgn.start.column = r->start.column + 1;
            SelRgn.end.column = r->end.column + 2;
        } else {
            SelRgn.start.column = r->end.column + 1;
            SelRgn.end.column = r->start.column + 2;
        }
        rc = CGimmeLinePtr( SelRgn.start.line, &fcb, &line );
        if( rc == ERR_NO_ERR ) {
            SelRgn.start_col_v = WinVirtualCursorPosition( line->data,
                                                           SelRgn.start.column );
        }
    }
    SelRgn.selected = TRUE;
    updateRegion();
    return( ERR_NO_ERR );

} /* SetSelectedRegion */
Exemplo n.º 7
0
/*
 * getBracketLoc - find a matching '(' for a ')'
 */
static vi_rc getBracketLoc( i_mark *pos )
{
    vi_rc       rc;
    char        tmp[3];
    int         len;
//    linenum     lne;

    tmp[0] = '\\';
    tmp[1] = ')';
    tmp[2] = 0;
//    lne = CurrentPos.line;
    RegExpAttrSave( -1, NULL );
    rc = GetFind( tmp, pos, &len, FINDFL_BACKWARDS | FINDFL_NOERROR | FINDFL_NOCHANGE );
    RegExpAttrRestore();
    if( pos->line != CurrentPos.line ) {
        return( ERR_FIND_NOT_FOUND );
    }
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }

    /*
     * find the matching '('
     */
    CurrentPos = *pos;
    CGimmeLinePtr( CurrentPos.line, &CurrentFcb, &CurrentLine );
    rc = FindMatch( pos );
    return( rc );

} /* getBracketLoc */
Exemplo n.º 8
0
/*
 * HideLineRange - hide/unhide a given line range
 */
vi_rc HideLineRange( linenum s, linenum e, bool unhide )
{
    vi_rc       rc;
    bool        hideval;
    fcb         *cfcb;
    line        *cline;
    char        *st;
    linenum     c;

    hideval = TRUE;
    if( unhide ) {
        hideval = FALSE;
    }

    for( c = s; c <= e; c++ ) {
        rc = CGimmeLinePtr( c, &cfcb, &cline );
        if( rc != ERR_NO_ERR ) {
            return( rc );
        }
        cline->u.ld.hidden = hideval;
    }

    DCDisplayAllLines();
    if( unhide ) {
        st = "revealed";
    } else {
        st = "hidden";
    }
    Message1( "%l lines %s", e - s + 1, st );
    EditFlags.Dotable = TRUE;
    return( DO_NOT_CLEAR_MESSAGE_WINDOW );

} /* HideLineRange */
Exemplo n.º 9
0
/*
 * GetHiddenLineCount - get number of hidden lines in a range
 */
linenum GetHiddenLineCount( linenum s, linenum e )
{
    line        *cline;
    fcb         *cfcb;
    int         i;
    linenum     cnt, tmp;

    if( s > e ) {
        tmp = s;
        s = e;
        e = tmp;
    }
    i = CGimmeLinePtr( s, &cfcb, &cline );
    if( i ) {
        return( 0L );
    }
    cnt = 0L;
    while( s <= e ) {
        if( cline->u.ld.hidden ) {
            cnt++;
        }
        s++;
        i = CGimmeNextLinePtr( &cfcb, &cline );
        if( i ) {
            break;
        }
    }
    return( cnt );

} /* GetHiddenLineCount */
Exemplo n.º 10
0
/*
 * CAdvanceToLine - advance to given line in file
 */
vi_rc CAdvanceToLine( linenum l )
{
    fcb         *cfcb;
    line        *cline;
    vi_rc       rc;

    rc = CGimmeLinePtr( l, &cfcb, &cline );
    return( rc );

} /* CAdvanceToLine */
Exemplo n.º 11
0
int LineLength( linenum l )
{
    line        *line;
    fcb         *fcb;
    vi_rc       rc;

    rc = CGimmeLinePtr( l, &fcb, &line );
    if( rc != ERR_NO_ERR ) {
        return( 0 );
    }
    return( line->len );
}
Exemplo n.º 12
0
/*
 * SaveAndResetFilePos - as it sounds
 */
vi_rc SaveAndResetFilePos( linenum n1 )
{
    vi_rc   rc;

    SaveCurrentFilePos();
    SetCurrentLineNumber( n1 );
    rc = CGimmeLinePtr( n1, &CurrentFcb, &CurrentLine );
    if( rc != ERR_NO_ERR ) {
        RestoreCurrentFilePos();
    }
    return( rc );

} /* SaveAndResetFilePos */
Exemplo n.º 13
0
/*
 * SplitUpLine - split up a line with SPLIT_CHAR's in them
 */
linenum SplitUpLine( linenum cl )
{
    linenum     extra = 0;
    int         j, i, k;
    char        *buff;

    /*
     * run through, and for every 0x01, make a new line
     */
    for( ;; ) {

        /*
         * get current line
         */
        CurrentPos.line = cl + extra;
        CGimmeLinePtr( CurrentPos.line, &CurrentFcb, &CurrentLine );
        GetCurrentLine();

        for( i = 0; i <= WorkLine->len; i++ ) {
            /*
             * found a place to split.  make this line shorter,
             * and create a new line with the rest of the data
             * for this line
             */
            if( WorkLine->data[i] == SPLIT_CHAR ) {
                buff = StaticAlloc();
                k = 0;
                for( j = i + 1; j <= WorkLine->len; j++ ) {
                    buff[k++] = WorkLine->data[j];
                }
                WorkLine->data[i] = 0;
                WorkLine->len = i;
                ReplaceCurrentLine();
                AddNewLineAroundCurrent( buff, k - 1, INSERT_AFTER );
                extra++;
                StaticFree( buff );
                break;
            }

            /*
             * at the very end, undo what we did and go back
             */
            if( WorkLine->data[i] == 0 ) {
                ReplaceCurrentLine();
                UndoInsert( cl + 1, cl + extra, UndoStack );
                return( extra );
            }
        }
    }

} /* SplitUpLine */
Exemplo n.º 14
0
/*
 * GetHiddenRange - get range of lines hidden around a given line
 */
void GetHiddenRange( linenum l, linenum *s, linenum *e )
{
    line        *cline, *oline;
    fcb         *cfcb, *ofcb;
    int         i;

    (*s) = (*e) = l;

    i = CGimmeLinePtr( l, &ofcb, &oline );
    if( i ) {
        return;
    }

    /*
     * go back
     */
    cfcb = ofcb;
    cline = oline;
    for( ;; ) {
        i = GimmePrevLinePtr( &cfcb, &cline );
        if( i ) {
            break;
        }
        if( cline->u.ld.hidden ) {
            (*s)--;
            continue;
        } else {
            break;
        }
    }

    /*
     * go forwards
     */
    cfcb = ofcb;
    cline = oline;
    for( ;; ) {
        i = CGimmeNextLinePtr( &cfcb, &cline );
        if( i ) {
            break;
        }
        if( cline->u.ld.hidden ) {
            (*e)++;
            continue;
        } else {
            break;
        }
    }

} /* GetHiddenRange */
Exemplo n.º 15
0
void InitFORTRANFlags( linenum line_no )
{
    char    *text;
//    char    *start;
    line    *line;
    fcb     *fcb;
    vi_rc   rc;
    int     numQuotes = 0;

    flags.inString = false;

    rc = CGimmeLinePtr( line_no, &fcb, &line );
    if( rc != ERR_NO_ERR ) {
        // probably past eof
        return;
    }

    if( isInitialLine( line ) ) {
        return;
    }

    for( ;; ) {
        rc = GimmePrevLinePtr( &fcb, &line );
        if( rc != ERR_NO_ERR ) {
            break;
        }
        text = line->u.ld.nolinedata ? WorkLine->data : line->data;
//        start = text;
        if( iscomment( *text ) ) {
            continue;
        }
        while( *text != '\0' ) {
            if( *text == '!' ) {
                // rest of line is part of a comment
                break;
            } else if( *text == '\'' ) {
                numQuotes ^= 1;
            }
            text++;
        }
        if( isInitialLine( line ) ) {
            break;
        }
    }

    if( numQuotes == 1 ) {
        flags.inString = true;
    }
}
Exemplo n.º 16
0
/*
 * MovePosition - move to a screen position
 */
vi_rc MovePosition( void )
{
    linenum     lne, lines;
    vi_key      key;
    vi_rc       rc;

    if( RepeatDigits == 0 ) {
        lne = CurrentPos.line;
    } else {
        lne = GetRepeatCount();
        if( IsPastLastLine( lne ) ) {
            return( ERR_INVALID_REDRAW );
        }
    }
    lines = WindowAuxInfo( CurrentWindow, WIND_INFO_TEXT_LINES );
    key = GetNextEvent( false );
    switch( key ) {
    case '.':
        LeftTopPos.line = lne - lines / 2;
        break;
    case VI_KEY( ENTER ):
        LeftTopPos.line = lne;
        break;
    case '-':
        LeftTopPos.line = lne - lines + 1;
        break;
    default:
        return( ERR_INVALID_REDRAW );
    }
    if( LeftTopPos.line < 1 ) {
        LeftTopPos.line = 1;
    }
    SetCurrentLineNumber( lne );
    rc = CGimmeLinePtr( CurrentPos.line, &CurrentFcb, &CurrentLine );
    CurrentPos.column = 1;
    DCInvalidateAllLines();
    DCDisplayAllLines();
    if( rc == ERR_NO_ERR ) {
        rc = GoToColumnOnCurrentLine( FindStartOfCurrentLine() );
    }
    return( rc );

} /* MovePosition */
Exemplo n.º 17
0
/*
 * SetSelectedRegionFromLine - set the SelRgn w/ start_v
 */
vi_rc SetSelectedRegionFromLine( range *r, linenum lineno )
{
    vi_rc   rc;
    fcb     *fcb;
    line    *line;
    char    *data;

    SetSelectedRegion( r );

    rc = CGimmeLinePtr( lineno, &fcb, &line );
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }
    data = line->u.ld.nolinedata ? WorkLine->data : line->data;
    SelRgn.start_col_v = GetVirtualCursorPosition( data, SelRgn.start.column );

    return( ERR_NO_ERR );

} /* SetSelectedRegionFromLine */
Exemplo n.º 18
0
/*
 * findMatchingBrace find '{' for a '}'
 */
static vi_rc findMatchingBrace( i_mark *pos1 )
{
    vi_rc       rc;
    i_mark      pos2;

    rc = FindMatch( pos1 );
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }
    SaveCurrentFilePos();
    CurrentPos = *pos1;
    CGimmeLinePtr( CurrentPos.line, &CurrentFcb, &CurrentLine );

    rc = getBracketLoc( &pos2 );
    RestoreCurrentFilePos();
    if( rc == ERR_NO_ERR ) {
        *pos1 = pos2;
    }
    return( ERR_NO_ERR );

} /* findMatchingBrace */
Exemplo n.º 19
0
void DCDisplaySomeLines( int start, int end )
{
    int         i;
    dc          dc;
    linenum     line_no;
    line        *line;
    fcb         *cfcb;
    vi_rc       rc;

    if( EditFlags.DisplayHold || CurrentFile == NULL || CurrentInfo == NULL ) {
        return;
    }

    assert( CurrentInfo );

    if( CurrentInfo->dc_size == 0 ) {
        return;
    }
    CurrentFile->needs_display = true;
    shaveRange( &start, &end );

    cfcb = CurrentFcb;
    line_no = LeftTopPos.line + start;
    rc = CGimmeLinePtr( line_no, &cfcb, &line );
    if( rc != ERR_NO_ERR && rc != ERR_NO_SUCH_LINE ) {
        return;
    }
    CTurnOffFileDisplayBits();
    cfcb->on_display = true;

    dc = CurrentInfo->dc;
    dc += start;
    for( i = start; i <= end; i++ ) {
        dc->display = true;
        dc++;
    }
}
Exemplo n.º 20
0
/*
 * ptrFromMark: Return a character pointer to the position in some
 * line's data which is indicated by the given mark.
 */
static char *ptrFromMark( i_mark *curr )
{
    line        *line;
    fcb         *fcb;
    vi_rc       rc;
    char        *ptr;

    ptr = NULL;
    rc = CGimmeLinePtr( curr->line, &fcb, &line );
    if( rc == ERR_NO_ERR ) {
        if( curr->column > 0 && curr->column <= line->len ) {
            ptr = &(line->data[curr->column - 1]);
        } else if( !EditFlags.WordWrap ) {
            if( curr->column == 0 ) {
                ptr = &(line->data[curr->column]);
            } else {
                ptr = &(line->data[line->len - 1]);
            }
            noWrap = true;
        }
    }
    return( ptr );

} /* ptrFromMark */
Exemplo n.º 21
0
/*
 * changeOneLine: change the case for each character on the given line
 * from the starting column given by start_col (base 0) to the column
 * denoted by end_col (base 0).
 */
static vi_rc changeOneLine( linenum line_num, int start_col, int end_col )
{
    line        *line;
    fcb         *fcb;
    int         num_cols, i;
    char        *s;
    vi_rc       rc;

    rc = CGimmeLinePtr( line_num, &fcb, &line );
    if( rc == ERR_NO_ERR ) {
        assert( end_col < line->len && end_col >= start_col );
        num_cols = end_col - start_col + 1;
        s = &line->data[start_col];
        for( i = 0; i < num_cols; i++ ) {
            if( isupper( *s ) ) {
                *s = tolower( *s );
            } else {
                *s = toupper( *s );
            }
            s++;
        }
    }
    return( rc );
}
Exemplo n.º 22
0
/*
 * IMCloseBrace - handle '}' in insert mode
 */
vi_rc IMCloseBrace( void )
{
    int         i, j;
    int         ts;
    fcb         *cfcb;
    line        *cline;
    vi_rc       rc;
    int         newcol;
    i_mark      pos;

    startNewLineUndo();
    insertChar( TRUE, FALSE );
    newcol = CurrentPos.column + 1;
    if( EditFlags.ShowMatch ) {
        ReplaceCurrentLine();
        rc = FindMatch( &pos );
        if( rc == ERR_NO_ERR ) {
            tempMatch( &pos );
        }
        GetCurrentLine();
    }
    if( EditFlags.CMode ) {
        i = 0;
        while( isspace( WorkLine->data[i] ) ) {
            i++;
        }
        if( WorkLine->data[i] == '}' ) {
            /*
             * added a {, so:
             *   find matching }
             *   find out indentation of that line
             *   shift current line over to that indentation
             *   set current indentation to that
             */

            ReplaceCurrentLine();
            rc = findMatchingBrace( &pos );
            if( rc == ERR_NO_ERR ) {
                newcol = VirtualColumnOnCurrentLine( CurrentPos.column );
                CGimmeLinePtr( pos.line, &cfcb, &cline );
                i = FindStartOfALine( cline );
                i = GetVirtualCursorPosition( cline->data, i );
                j = i - VirtualColumnOnCurrentLine( CurrentPos.column );
                ts = EditVars.ShiftWidth;
                if( j > 0 ) {
                    EditVars.ShiftWidth = j;
                    Shift( CurrentPos.line, CurrentPos.line, '>', FALSE );
                } else if( j < 0 ) {
                    EditVars.ShiftWidth = -j;
                    Shift( CurrentPos.line, CurrentPos.line, '<', FALSE );
                }
                EditVars.ShiftWidth = ts;
                newcol = 1 + RealColumnOnCurrentLine( j + newcol );
            }
            GetCurrentLine();
        }
    }
    GoToColumn( newcol, WorkLine->len + 1 );
    return( ERR_NO_ERR );

} /* IMCloseBrace */
Exemplo n.º 23
0
/*
 * SrcAssign - assign a value to a variable
 */
vi_rc SrcAssign( const char *data, vlist *vl )
{
    int         i, j, k, l;
    long        val;
    bool        rxflag = false;
    bool        envflag = false;
    bool        setflag = false;
    bool        expflag = false;
    bool        timeflag = false;
    bool        lnumflag = false;
    char        tmp[MAX_SRC_LINE], tmp1[MAX_SRC_LINE], name[MAX_SRC_LINE];
    const char  *v1;
    char        *t;
    vars        *v;
    jmp_buf     jmpaddr;
    time_t      tod;
    bool        check_end;
    char        tmpstr[MAX_STR];

    /*
     * get assign syntax :
     * ASSIGN %v = /v1/(r)($)(@)(x)(l)(t)
     * possible v1:
     *  strlen %a
     *  strchr %a ch
     *  substr %a n1 n2
     */
    data = GetNextWord1( data, tmp );
    if( *tmp == '\0' ) {
        return( ERR_SRC_INVALID_ASSIGN );
    }
    if( !VarName( name, tmp, vl ) ) {
        return( ERR_SRC_INVALID_ASSIGN );
    }
    data = GetNextWord1( data, tmp );
    if( *tmp == '\0' ) {
        return( ERR_SRC_INVALID_ASSIGN );
    }
    if( stricmp( tmp, "=" ) != 0 ) {
        return( ERR_SRC_INVALID_ASSIGN );
    }
    data = SkipLeadingSpaces( data );

    if( data[0] == '/' || data[0] == '"' ) {
        check_end = false;
        if( data[0] == '"' ) {
            data = GetNextWord( data, tmp, SingleQuote );
            if( data[0] == '"' ) {
                check_end = true;
            }
        } else {
            data = GetNextWord( data, tmp, SingleSlash );
            if( data[0] == '/' ) {
                check_end = true;
            }
        }
        if( check_end ) {
            for( ++data; data[0] != '\0'; data++ ) {
                switch( data[0] ) {
                case 't':
                    timeflag = true;
                    break;
                case 'r':
                    rxflag = true;
                    break;
                case '$':
                    envflag = true;
                    break;
                case '@':
                    setflag = true;
                    break;
                case 'x':
                    expflag = true;
                    break;
                case 'l':
                    lnumflag = true;
                    break;
                }
            }
        }
        Expand( tmp1, tmp, vl );
    } else {
        data = GetNextWord1( data, tmp );
        if( *tmp == '\0' ) {
            return( ERR_SRC_INVALID_ASSIGN );
        }
        j = Tokenize( StrTokens, tmp, false );
        if( j != TOK_INVALID ) {
            data = GetNextWord1( data, tmp );
            if( *tmp == '\0' ) {
                return( ERR_SRC_INVALID_ASSIGN );
            }
            if( !VarName( tmp1, tmp, vl ) ) {
                return( ERR_SRC_INVALID_ASSIGN );
            }
            v = VarFind( tmp1, vl );
            switch( j ) {
            case STR_T_STRLEN:
                if( v != NULL ) {
                    sprintf( tmp1, "%d", v->len );
                } else {
                    strcpy( tmp1, "0" );
                }
                break;
            case STR_T_SUBSTR:
                data = GetNextWord1( data, tmp );
                if( *tmp == '\0' ) {
                    return( ERR_SRC_INVALID_ASSIGN );
                }
                Expand( tmp1, tmp, vl );
                i = atoi( tmp1 ) - 1;
                data = GetNextWord1( data, tmp );
                if( *tmp == '\0' ) {
                    return( ERR_SRC_INVALID_ASSIGN );
                }
                Expand( tmp1, tmp, vl );
                j = atoi( tmp1 ) - 1;
                if( v == NULL ) {
                    tmp1[0] = '\0';
                    break;
                }
                if( j >= v->len || i < 0 ) {
                    tmp1[0] = '\0';
                } else {
                    l = 0;
                    for( k = i; k <= j; k++ ) {
                        tmp1[l++] = v->value[k];
                    }
                    tmp1[l] = '\0';
                }
                break;
            case STR_T_STRCHR:
                data = GetNextWord1( data, tmp );
                if( *tmp == '\0' ) {
                    return( ERR_SRC_INVALID_ASSIGN );
                }
                Expand( tmp1, tmp, vl );
                if( v == NULL ) {
                    j = -1;
                } else {
                    t = strchr( v->value, tmp1[0] );
                    if( t != NULL ) {
                        j = t - v->value;
                    } else {
                        j = -1;
                    }
                    j++;
                }
                sprintf( tmp1, "%d", j );
                break;
            }
        } else {
            Expand( tmp1, tmp, vl );
        }

    }
    /*
     * regular expression subs.
     */
    if( rxflag && CurrentRegularExpression != NULL ) {
        RegSub( CurrentRegularExpression, tmp1, tmp, CurrentPos.line );
        strcpy( tmp1, tmp );
    }

    /*
     * special processing
     */
    if( envflag ) {
        v1 = getenv( tmp1 );
        if( v1 == NULL ) {
            v1 = "";
        }
    } else if( setflag ) {
        v1 = GetASetVal( tmp1, tmpstr );
    } else if( timeflag ) {
        tod = time( NULL );
        strftime( tmp, sizeof( tmp ), tmp1, localtime( &tod ) );
        v1 = tmp;
    } else if( expflag || lnumflag ) {
        i = setjmp( jmpaddr );
        if( i != 0 ) {
            return( (vi_rc)i );
        }
        StartExprParse( tmp1, jmpaddr );
        val = GetConstExpr();
        if( lnumflag ) {
            fcb         *cfcb;
            line        *cline;
            vi_rc       rc;
            rc = CGimmeLinePtr( val, &cfcb, &cline );
            v1 = cline->data;
            if( rc != ERR_NO_ERR ) {
                v1 = "";
            }
        } else {
            v1 = ltoa( val, tmp1, EditVars.Radix );
        }
    } else {
        v1 = tmp1;
    }

    VarAddStr( name, v1, vl );
    return( ERR_NO_ERR );

} /* SrcAssign */
Exemplo n.º 24
0
/*
 * UpdateDrag - update selected region
 */
void UpdateDrag( window_id id, int win_x, int win_y )
{
    int         nx, ny, height;
    int         moveCursor;

    SelRgn.selected = TRUE;
    moveCursor = 0;
    height = WindowAuxInfo( CurrentWindow, WIND_INFO_TEXT_LINES );
#ifdef __WIN__
    if( id == CurrentWindow && InsideWindow( id, MouseX, MouseY ) ) {
#else
    if( id == CurrentWindow && InsideWindow( id, win_x, win_y ) ) {
#endif
        ny = LeftTopPos.line + win_y - 1;
        if( ny > CurrentFile->fcbs.tail->end_line ) {
            ny = CurrentFile->fcbs.tail->end_line;
            moveCursor = 1;
        } else if( ny < 1 ) {
            ny = 1;
            moveCursor = -1;
        }
        GoToLineRelCurs( ny );
        win_x += LeftTopPos.column;
        nx = RealColumnOnCurrentLine( win_x );
        GoToColumnOnCurrentLine( nx );
    } else {
#ifndef __WIN__
        if( MouseRow >= WindowAuxInfo( CurrentWindow, WIND_INFO_Y2 ) ) {
            GoToLineRelCurs( LeftTopPos.line + height );
        } else if( MouseRow <= WindowAuxInfo( CurrentWindow, WIND_INFO_Y1 ) ) {
            GoToLineRelCurs( LeftTopPos.line - 1 );
        } else if( MouseCol <= WindowAuxInfo( CurrentWindow, WIND_INFO_X1 ) ) {
            GoToColumnOnCurrentLine( LeftTopPos.column - 1 );
        } else if( MouseCol >= WindowAuxInfo( CurrentWindow, WIND_INFO_X2 ) ) {
            GoToColumnOnCurrentLine( LeftTopPos.column + WindowAuxInfo( CurrentWindow, WIND_INFO_WIDTH ));
        }
#else
        {
            RECT            rect;

            GetClientRect( CurrentWindow, &rect );
            if( MouseY > rect.bottom ) {
                ny = LeftTopPos.line + height;
                if( ny > CurrentFile->fcbs.tail->end_line ) {
                    ny = CurrentFile->fcbs.tail->end_line;
                    moveCursor = 1;
                }
                GoToLineRelCurs( ny );
            } else if( MouseY < 0 ) {
                ny = LeftTopPos.line - 1;
                if( ny < 1 ) {
                    ny = 1;
                    moveCursor = -1;
                }
                GoToLineRelCurs( ny );
            } else if( MouseX < 0 ) {
                GoToColumnOnCurrentLine( LeftTopPos.column - 1 );
            } else if( MouseX > rect.right ) {
                if( EditFlags.Modeless ) {
                    GoToColumnOnCurrentLine( 1 + LeftTopPos.column +
                        WindowAuxInfo( CurrentWindow, WIND_INFO_TEXT_COLS ) );
                } else {
                    GoToColumnOnCurrentLine( LeftTopPos.column +
                        WindowAuxInfo( CurrentWindow, WIND_INFO_TEXT_COLS ) );
                }
            }
        }
#endif
    }

    if( moveCursor == -1 ) {
        GoToColumnOnCurrentLine( 1 );
    } else if( moveCursor == 1 ) {
        GoToColumnOnCurrentLine( CurrentFile->fcbs.tail->lines.tail->len + 1 );
    }

} /* UpdateDrag */

/*
 * UpdateCursorDrag - update drag after cursor movement
 */
void UpdateCursorDrag( void )
{
    if( !EditFlags.Dragging ) {
        return;
    }
    if( SelRgn.end.line == CurrentPos.line && SelRgn.end.column == CurrentPos.column ) {
        return;
    }
#ifndef __WIN__
    markRegion( FALSE );
#endif
    SelRgn.end = CurrentPos;
    if( EditFlags.LineBased == FALSE ) {
        SelRgn.lines = FALSE;
    } else if( SelRgn.start.line != SelRgn.end.line ) {
        SelRgn.lines = TRUE;
    } else if( SelRgn.start.column == SelRgn.end.column ) {
        SelRgn.lines = TRUE;
    } else {
        SelRgn.lines = FALSE;
    }
    updateRegion();

} /* UpdateCursorDrag */

/*
 * SetSelRegionCols - set selected region on a line
 */
void SetSelRegionCols( linenum sl, int sc, int ec )
{
    vi_rc   rc;
    line    *line;
    fcb     *fcb;
    char    *data;

    SelRgn.lines = FALSE;
    SelRgn.selected = TRUE;
    SelRgn.start.line = SelRgn.end.line = sl;
    SelRgn.start.column = sc;
    SelRgn.end.column = ec + 1;
    SelRgn.start_col_v = 0;
    rc = CGimmeLinePtr( sl, &fcb, &line );
    if( rc == ERR_NO_ERR ) {
        data = ( line->u.ld.nolinedata ) ? WorkLine->data : line->data;
        SelRgn.start_col_v = GetVirtualCursorPosition( data, SelRgn.start.column );
    }

    updateRegion();
    DCUpdate();

} /* SetSelRegionCols */
Exemplo n.º 25
0
/*
 * setLineCol - set up line and column to start search at
 */
static vi_rc setLineCol( char *st, i_mark *pos, find_type flags )
{
    fcb         *cfcb;
    line        *cline;
    bool        wrapped;

    /*
     * get next position
     */
    if( st[0] == 0 ) {
        if( lastFind == NULL ) {
            return( ERR_NO_PREVIOUS_SEARCH_STRING );
        }
        if( lastPos.line != 0 && currPos.column == CurrentPos.column &&
            currPos.line == CurrentPos.line ) {
            *pos = lastPos;
            if( flags & FINDFL_FORWARD ) {
                pos->column += 1;
            } else {
                pos->column -= 2;
            }
        } else {
            *pos = CurrentPos;
            if( flags & FINDFL_FORWARD ) {
                pos->column += 0;
            } else {
                pos->column -= 2;
            }
        }
        AddString2( &sStr, lastFind );
    } else {
        if( !(flags & FINDFL_NOCHANGE) ) {
            AddString2( &lastFind, st );
        }
        AddString2( &sStr, st );
        *pos = CurrentPos;
        if( flags & FINDFL_FORWARD ) {
            pos->column += 0;
        } else {
            pos->column -= 2;
        }
    }

    /*
     * wrap if needed
     */
    if( flags & FINDFL_NEXTLINE ) {
        wrapped = FALSE;
        if( flags & FINDFL_FORWARD ) {
            pos->column = 0;
            pos->line += 1;
            if( IsPastLastLine( pos->line ) ) {
                pos->line = 1;
                wrapped = TRUE;
            }
        } else {
            pos->line -= 1;
            if( pos->line == 0 ) {
                CFindLastLine( &pos->line );
                wrapped = TRUE;
            }
            CGimmeLinePtr( pos->line, &cfcb, &cline );
            pos->column = cline->len - 1;
            if( pos->column < 0 ) {
                pos->column = 0;
            }
        }
        if( wrapped && !(flags & FINDFL_WRAP) ) {
            if( flags & FINDFL_FORWARD ) {
                return( ERR_FIND_END_OF_FILE );
            } else {
                return( ERR_FIND_TOP_OF_FILE );
            }
        }
    }

    return( ERR_NO_ERR );

} /* setLineCol */
Exemplo n.º 26
0
static void getLiteral( ss_block *ss_new, char *start, int skip )
{
    char    *text;
    char    lastchar = '\0';
    bool    empty;
    bool    multiLine = flags.inString;
    line    *line;
    fcb     *fcb;
    char    *data;
    vi_rc   rc;

    empty = true;
    for( text = start + skip; *text != '\0'; ++text ) {
        if( text[0] == '\'' ) {
            if( text[1] != '\'' )
                break;
            ++text;
        }
        empty = false;
    }
    flags.inString = false;
    if( *text == '\0' ) {
        // if next line a continuation line, then flag flags.inString, else
        // flag unterminated string
        rc = CGimmeLinePtr( thisLine + 1, &fcb, &line );
        for( ;; ) {
            if( rc != ERR_NO_ERR ) {
                break;
            }
            data = (line->u.ld.nolinedata) ? WorkLine->data : line->data;
            if( !iscomment( data[0] ) ) {
                break;
            }
            rc = CGimmeNextLinePtr( &fcb, &line );
        }
        ss_new->type = SE_INVALIDTEXT;
        if( rc == ERR_NO_ERR && !isInitialLine( line ) ) {
            ss_new->type = SE_STRING;
            flags.inString = true;
        }
    } else {
        text++;
        lastchar = tolower( *text );
        switch( lastchar ) {
        case 'c':
            text++;
            ss_new->type = SE_STRING;
            break;
        case 'x':
            text++;
            ss_new->type = SE_HEX;
            break;
        case 'o':
            text++;
            ss_new->type = SE_OCTAL;
            break;
        default:
            // hard to say if invalid or not - take a guess
            if( islower( *text ) ) {
                text++;
                ss_new->type = SE_INVALIDTEXT;
            } else {
                ss_new->type = SE_STRING;
            }
            break;
        }
    }
    ss_new->len = text - start;
    if( empty && !multiLine ) {
        ss_new->type = SE_INVALIDTEXT;
    }
}
Exemplo n.º 27
0
/*
 * goToLine - go to a specified line number
 */
static vi_rc goToLine( linenum lineno, bool relcurs )
{
    int         text_lines, tl;
    linenum     diff, cwl, nwl;
//    linenum   s, e, hiddcnt;
    bool        dispall, pageshift;
    fcb         *cfcb;
    line        *cline;
    int         pad;
    vi_rc       rc;

    if( lineno < 1 ) {
        return( ERR_NO_SUCH_LINE );
    }

    /*
     * get pointer to requested line
     */
    rc = CGimmeLinePtr( lineno, &cfcb, &cline );
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }
#if 0
    if( cline->u.ld.hidden ) {
        GetHiddenRange( lineno, &s, &e );
        if( lineno > CurrentPos.line ) {
            lineno = e + 1;
        } else {
            lineno = s - 1;
        }
        rc = CGimmeLinePtr( lineno, &cfcb, &cline );
        if( rc != ERR_NO_ERR ) {
            return( rc );
        }
    }
#endif

    /*
     * compute new location
     */
    CurrentFcb = cfcb;
    CurrentLine = cline;
    diff = lineno - CurrentPos.line;
    if( diff == 0 && !EditFlags.GlobalInProgress ) {
        return( ERR_NO_ERR );
    }
    cwl = CurrentPos.line - LeftTopPos.line + 1;
    nwl = cwl + diff;

    /*
     * if we go off the window, relocate
     */
    pageshift = false;
    dispall = false;

    text_lines = WindowAuxInfo( current_window_id, WIND_INFO_TEXT_LINES );
    if( nwl < 1 || nwl > text_lines ) {
        tl = text_lines / 2;
        if( !relcurs ) {
            LeftTopPos.line = lineno - tl;
        } else {
            LeftTopPos.line = lineno + 1 - cwl;
            pad = ( EditFlags.JumpyScroll ) ? 1 : 0;
            if( diff > 0 ) {
                LeftTopPos.line += pad;
                diff += pad;
            } else {
                LeftTopPos.line -= pad;
                diff -= pad;
            }
            if( diff > -tl && diff < tl && !dispall ) {
                pageshift = true;
            }
        }
        if( LeftTopPos.line < 1 ) {
            assert( diff <= 0 ); // < -> <= W.Briscoe 20031003 to avoid debug build failure of
            // C:\watcom\source\docs\nt) wmake -h -f ..\mif\master.mif hbook=wccerrs dotarget=nt
            diff += ( 1 - LeftTopPos.line );
            LeftTopPos.line = 1;
        }
        if( LeftTopPos.line > lineno ) {
            assert( diff > 0 );
            diff = LeftTopPos.line - lineno;
            LeftTopPos.line = lineno;
        }
        dispall = true;
    }
#if 0
    hiddcnt = GetHiddenLineCount( LeftTopPos.line, lineno );
    if( hiddcnt > 0 ) {
        pageshift = false;
        dispall = true;
    }
#endif

    if( CheckCurrentColumn() || EditFlags.Dragging ) {
        // pageshift wont help if we also have to column shift
        // and not really useful if dragging

        dispall = true;
        pageshift = false;
    }


    /* call SetCurrentLineNumber AFTER LeftTopPos.line set & CurrentColumn checked
    */
    SetCurrentLineNumber( lineno );

    if( pageshift ) {
        dispall = false;
        ShiftWindowUpDown( current_window_id, diff );
        if( EditFlags.LineNumbers ) {
            ShiftWindowUpDown( curr_num_window_id, diff );
        }
        if( diff > 0 ) {
            DCDisplaySomeLines( text_lines - diff, text_lines - 1 );
        } else {
            DCDisplaySomeLines( 0, -diff - 1 );
        }
    }
    UpdateStatusWindow();
    SetWindowCursor();
    if( dispall ) {
        DCInvalidateAllLines(); // lines definitely invalid
        DCDisplayAllLines();
    }
    return( ERR_NO_ERR );

} /* goToLine */
Exemplo n.º 28
0
void InitPerlFlags( linenum line_no )
{
    fcb     *fcb;
    char    *text;
    line    *thisline;
//    line    *topline;
    vi_rc   rc;
    bool    withinQuotes = false;
    line    *line;
    bool    inBlock = false;

    flags.inString = false;
    flags.beforeRegExp = true;
    flags.doubleRegExp = false;

    CGimmeLinePtr( line_no, &fcb, &thisline );
    line = thisline;
    rc = GimmePrevLinePtr( &fcb, &line );
    while( rc == ERR_NO_ERR ) {
        if( line->data[line->len - 1] != '\\' ) {
            break;
        }
        inBlock = true;
        rc = GimmePrevLinePtr( &fcb, &line );
    }

    if( rc == ERR_NO_ERR ) {
//        topline = line;
        if( inBlock ) {
            CGimmeNextLinePtr( &fcb, &line );
        }
    } else {
//        topline = NULL;
        if( inBlock ) {
            CGimmeLinePtr( 1, &fcb, &line );
        } else {
            return;
        }
    }

    if( inBlock ) {
        // parse down through lines, noticing "
        while( line != thisline ) {
            text = line->data;
            while( *text ) {
                if( *text == '"' ) {
                    if( !withinQuotes ) {
                        withinQuotes = true;
                    } else if( *(text - 1) != '\\' || *(text - 2) == '\\' ) {
                        withinQuotes = false;
                    }
                }
                text++;
            }
            rc = CGimmeNextLinePtr( &fcb, &line );
        }

        if( withinQuotes ) {
            flags.inString = true;
        }
    }
}
Exemplo n.º 29
0
void InitRexxFlags( linenum line_no )
{
    fcb     *fcb;
    char    *text;
    char    *starttext;
    line    *thisline;
    line    *topline;
    char    topChar;
    vi_rc   rc;
    bool    withinQuotes = false;
    line    *line;
    bool    inBlock = false;

    flags.inCComment = false;
    flags.inCPPComment = false;
    flags.inString = false;
    flags.inPreprocessor = false;

    CGimmeLinePtr( line_no, &fcb, &thisline );
    line = thisline;
    while( (rc = GimmePrevLinePtr( &fcb, &line )) == ERR_NO_ERR ) {
        if( line->data[line->len - 1] != '\\' ) {
            break;
        }
        inBlock = true;
    }

    if( rc == ERR_NO_ERR ) {
        topline = line;
        if( inBlock ) {
            CGimmeNextLinePtr( &fcb, &line );
        }
    } else {
        topline = NULL;
        if( inBlock ) {
            CGimmeLinePtr( 1, &fcb, &line );
        } else {
            return;
        }
    }

    if( inBlock ) {
        // jot down whether it started with #
        text = line->data;
        while( *text != '\0' && isspace( *text ) ) {
            text++;
        }
        topChar = *text;

        // parse down through lines, noticing /*, */ and "
        while( line != thisline ) {
            for( text = line->data; ; ++text ) {
                for( ; *text != '\0' && *text != '/'; ++text ) {
                    if( text[0] == '"' ) {
                        if( !withinQuotes ) {
                            withinQuotes = true;
                        } else if( text[-1] != '\\' || text[-2] == '\\' ) {
                            withinQuotes = false;
                        }
                    }
                }
                if( text[0] == '\0' ) {
                    break;
                }
                if( !withinQuotes ) {
                    if( text[-1] == '/' ) {
                        flags.inCPPComment = true;
                    } else if( text[1] == '*' ) {
                        flags.inCComment = true;
                        lenCComment = 100;
                    }
                }
                if( text[-1] == '*' && !withinQuotes ) {
                    flags.inCComment = false;
                }
            }
            rc = CGimmeNextLinePtr( &fcb, &line );
        }

        // if not in a comment (and none above), we may be string or pp
        if( !flags.inCComment ) {
            if( topChar == '#' && !EditFlags.PPKeywordOnly ) {
                flags.inPreprocessor = true;
            }
            if( withinQuotes ) {
                flags.inString = true;
            }
        }
    }

    if( topline == NULL ) {
        return;
    }

    if( !flags.inCComment ) {
        // keep going above multi-line thing till hit /* or */
        line = topline;
        do {
            starttext = line->data;
            for( text = starttext + line->len; ; --text ) {
                while( text != starttext && *text != '/' ) {
                    text--;
                }
                if( text[1] == '*' && text[0] == '/' && text[-1] != '/' ) {
                    if( text == starttext ) {
                        flags.inCComment = true;
                        lenCComment = 100;
                        return;
                    }
                    withinQuotes = false;
                    do {
                        text--;
                        if( text[0] == '"' ) {
                            if( !withinQuotes ) {
                                withinQuotes = true;
                            } else if( text[-1] != '\\' || text[-2] == '\\' ) {
                                withinQuotes = false;
                            }
                        }
                    } while( text != starttext );
                    if( withinQuotes ) {
                        flags.inString = true;
                    } else {
                        flags.inCComment = true;
                        lenCComment = 100;
                    }
                    return;
                }
                if( text == starttext ) {
                    break;
                }
                if( text[-1] == '*' ) {
                    // we may actually be in a string, but that's extreme
                    // (if this becomes a problem, count the "s to beginning
                    // of line, check if multiline, etc. etc.)
                    return;
                }
            }
            rc = GimmePrevLinePtr( &fcb, &line );
        } while( rc == ERR_NO_ERR );
    }
}
Exemplo n.º 30
0
/*
 * 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 */