Beispiel #1
0
/*
 * genItem - generate a src file item
 */
static void genItem( int token, label where )
{
    sfile       *tsf;

    tsf = MemAlloc( sizeof( sfile ) );

    tsf->arg1 = NULL;
    tsf->arg2 = NULL;
    tsf->data = NULL;
    tsf->token = token;
    tsf->line = CurrentSrcLine;
    tsf->hasvar = hasVar;
    tsf->branchcond = COND_FALSE;

    if( where != NULL ) {
        AddString( &(tsf->data), where );
    }

    InsertLLItemAfter( (ss **)&tmpTail, (ss *)tmpTail, (ss *)tsf );

} /* genItem */
Beispiel #2
0
/*
 * InsertNewLine - do just that
 */
void InsertNewLine( line *who, line_list *linelist, char *data, int copylen,
                    insert_dir dir )
{
    line        *cl;

    if( copylen <= 0 ) {
        data = NULL;
        copylen = 0;
    }
    cl = LineAlloc( data, copylen );
    if( linelist->head == NULL ) {
        AddLLItemAtEnd( (ss **)&linelist->head, (ss **)&linelist->tail, (ss *)cl );
    } else {
        if( dir == INSERT_AFTER ) {
            InsertLLItemAfter( (ss **)&linelist->tail, (ss *)who, (ss *)cl );
        } else {
            InsertLLItemBefore( (ss **)&linelist->head, (ss *)who, (ss *)cl );
        }
    }

} /* InsertNewLine */
Beispiel #3
0
/*
 * createNewFile - create new file entry
 */
static vi_rc createNewFile( char *name, bool same_file )
{
    int         height;
    window_id   cw;
    info        *tmp;
    vi_rc       rc;

    /*
     * test that we can create this file
     */
    tmp = NULL;
    if( !same_file ) {
        rc = FileExists( name );
        if( !(rc == ERR_READ_ONLY_FILE || rc == ERR_NO_ERR || rc == ERR_FILE_EXISTS) ) {
            return( rc );
        }
    } else {
        if( name != NULL ) {
            for( tmp = InfoHead; tmp != NULL; tmp = tmp->next ) {
                if( !strcmp( tmp->CurrentFile->name, name ) ) {
                    break;
                }
            }
        }
        if( tmp == NULL )  {
            return( ERR_FILE_NOT_FOUND );
        }
        if( tmp->CurrentFile->dup_count > MAX_DUPLICATE_FILES ) {
            return( ERR_WIND_NO_MORE_WINDOWS );
        }
    }

    /*
     * get new window
     */
    rc = NewWindow2( &cw, &editw_info );
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }
#ifdef __WIN__
    if( !strncmp( name, "untitled", 8 ) ) {
        // better yet, pass normal/maximize flag to NewWindow2...
        ShowWindow( cw, SW_SHOWMAXIMIZED );
    }
#endif
    SetBorderGadgets( cw, EditFlags.WindowGadgets );

    /*
     * get new file entry, and read the data
     */

    if( same_file ) {
        CurrentFile = tmp->CurrentFile;
        CurrentFile->dup_count++;
        SetFileWindowTitle( CurrentWindow, CurrentInfo, true );
        tmp = CurrentInfo;
        CurrentInfo = MemAlloc( sizeof( *CurrentInfo ) );
        FTSRunCmds( name );

        rc = ERR_NO_ERR;
    } else {
        bool crlf_reached;

        crlf_reached = false;
        tmp = CurrentInfo;
        CurrentInfo = MemAlloc( sizeof( *CurrentInfo ) );
        FTSRunCmds( name );
        height = editw_info.y2 - editw_info.y1 + 1;

        CurrentFile = FileAlloc( name );
        rc = OpenFcbData( CurrentFile );
        for( ; rc == ERR_NO_ERR; ) {
            rc = ReadFcbData( CurrentFile, &crlf_reached );
            if( rc == ERR_NO_ERR && !CurrentFile->is_stdio ) {
                if( EditFlags.BreakPressed || !EditFlags.ReadEntireFile ) {
                    if( CurrentFile->fcbs.tail->end_line > height ) {
                        break;
                    }
                }
            }
        }
        if( rc != ERR_NO_ERR && rc != ERR_FILE_NOT_FOUND && rc != END_OF_FILE ) {
            MemFree( CurrentInfo );
            CurrentInfo = tmp;
            FileFree( CurrentFile );
            CloseAWindow( cw );
            return( rc );
        }
        if( rc == ERR_FILE_NOT_FOUND ) {
            rc = NEW_FILE;
            EditFlags.NewFile = true;
            CurrentFile->write_crlf = FileSysNeedsCR( CurrentFile->handle );
#ifdef __UNIX__
            CurrentFile->attr = PMODE_RW;
#endif
        } else {
            rc = ERR_NO_ERR;
            CurrentFile->write_crlf = crlf_reached;
            EditFlags.NewFile = false;
#ifdef __UNIX__
            {
                struct stat     sb;
                stat( name, &sb );
                CurrentFile->attr = sb.st_mode & ~S_IFMT;
            }
#endif
        }
        CurrentFile->check_readonly = true;
    }

    /*
     * create info entry
     */
    CurrentPos.line = 0;
    CurrentPos.column = 1;
    VirtualColumnDesired = 1;
    LeftTopPos.line = 1;
    LeftTopPos.column = 0;
    if( !same_file ) {
        AllocateUndoStacks();
    }
    AllocateMarkList();
    CurrentWindow = cw;
    CurrentInfo->DuplicateID = CurrentFile->dup_count;
    CurrentInfo->CurrentWindow = cw;
    LangInit( CurrentInfo->fsi.Language );
#ifdef __WIN__
    {
        window_data     *wd;
        wd = DATA_FROM_ID( cw );
        wd->info = CurrentInfo;
    }
#endif
    DCCreate();
    SetFileWindowTitle( CurrentWindow, CurrentInfo, true );

    /*
     * set current file info
     */
    CurrentFcb = CurrentFile->fcbs.head;
    CurrentLine = CurrentFcb->lines.head;

    if( EditFlags.LineNumbers ) {
        LineNumbersSetup();
    }

    if( tmp != NULL ) {
        InsertLLItemAfter( (ss **)&InfoTail, (ss *)tmp, (ss *)CurrentInfo );
    } else {
        AddLLItemAtEnd( (ss **)&InfoHead, (ss **)&InfoTail, (ss *)CurrentInfo );
    }

    return( rc );

} /* createNewFile */
Beispiel #4
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 */
Beispiel #5
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 */