/* * GimmeLinePtr - give a pointer to line data */ vi_rc GimmeLinePtr( linenum lineno, file *cfile, fcb **cfcb, line **cline ) { vi_rc rc; fcb *tfcb; rc = FindFcbWithLine( lineno, cfile, &tfcb ); if( rc != ERR_NO_ERR ) { return( rc ); } rc = GimmeLinePtrFromFcb( lineno, tfcb, cline ); if( rc != ERR_NO_ERR ) { return( rc ); } *cfcb = tfcb; return( ERR_NO_ERR ); } /* GimmeLinePtr */
/* * CFindLastLine - find last line in file */ vi_rc CFindLastLine( linenum *ll ) { vi_rc rc; fcb *cfcb; if( CurrentFile == NULL ) { return( ERR_NO_FILE ); } if( !CurrentFile->bytes_pending ) { *ll = CurrentFile->fcbs.tail->end_line; return( ERR_NO_ERR ); } rc = FindFcbWithLine( -1, CurrentFile, &cfcb ); if( rc != ERR_NO_ERR ) { return( rc ); } *ll = cfcb->end_line; return( ERR_NO_ERR ); } /* CFindLastLine */
/* * SaveFile - save data from current file */ vi_rc SaveFile( char *name, linenum start, linenum end, int dammit ) { int i; bool existflag = FALSE, restpath = FALSE, makerw = FALSE; char *fn; fcb *cfcb, *sfcb, *efcb; linenum s, e, lc; long bc = 0; status_type lastst; vi_rc rc; int write_crlf; if( CurrentFile == NULL ) { return( ERR_NO_FILE ); } /* * get file name */ if( name == NULL ) { if( CurrentFile->viewonly ) { return( ERR_FILE_VIEW_ONLY ); } if( CFileReadOnly() ) { rc = readOnlyCheck(); if( rc != ERR_NO_ERR ) { return( ERR_READ_ONLY_FILE ); } makerw = TRUE; } fn = CurrentFile->name; restpath = TRUE; } else { existflag = TRUE; fn = name; } if( fn[0] == 0 ) { return( ERR_NO_FILE_NAME ); } if( SameFile( fn, CurrentFile->name ) ) { if( CurrentFile->viewonly ) { return( ERR_FILE_VIEW_ONLY ); } } if( dammit ) { existflag = FALSE; } /* * get range and fcbs */ if( start == -1L && end == -1L ) { s = 1L; rc = CFindLastLine( &e ); if( rc != ERR_NO_ERR ) { return( rc ); } } else { s = start; e = end; } lc = e - s + 1; rc = FindFcbWithLine( s, CurrentFile, &sfcb ); if( rc != ERR_NO_ERR ) { return( rc ); } rc = FindFcbWithLine( e, CurrentFile, &efcb ); if( rc != ERR_NO_ERR ) { return( rc ); } if( restpath ) { rc = ChangeDirectory( CurrentFile->home ); if( rc != ERR_NO_ERR ) { return( rc ); } } if( !CurrentFile->is_stdio ) { if( makerw ) { chmod( fn, PMODE_RW ); } rc = FileOpen( fn, existflag, O_TRUNC | O_WRONLY | O_BINARY | O_CREAT, WRITEATTRS, &fileHandle); if( rc != ERR_NO_ERR ) { Message1( strerror( errno ) ); return( rc ); } } else { fileHandle = 0; #ifdef __WATCOMC__ setmode( fileno( stdout ), O_BINARY ); #endif } /* * start writing fcbs */ #ifdef __WIN__ ToggleHourglass( TRUE ); #endif if( EditFlags.CRLFAutoDetect ) { write_crlf = CurrentFile->write_crlf; } else { write_crlf = EditFlags.WriteCRLF; } lastst = UpdateCurrentStatus( CSTATUS_WRITING ); for( cfcb = sfcb; cfcb != efcb; cfcb = cfcb->next ) { rc = writeRange( s, cfcb->end_line, cfcb, &bc, write_crlf, TRUE ); if( rc != ERR_NO_ERR ) { #ifdef __WIN__ ToggleHourglass( FALSE ); #endif UpdateCurrentStatus( lastst ); return( rc ); } s = cfcb->end_line + 1; } /* * last bit */ rc = writeRange( s, e, efcb, &bc, write_crlf, EditFlags.LastEOL ); #ifdef __WIN__ ToggleHourglass( FALSE ); #endif UpdateCurrentStatus( lastst ); if( rc != ERR_NO_ERR ) { return( rc ); } if( !CurrentFile->is_stdio ) { i = close( fileHandle ); if( makerw ) { chmod( fn, PMODE_R ); } if( i == -1 ) { Message1( strerror( errno ) ); return( ERR_FILE_CLOSE ); } } if( restpath ) { rc = ChangeDirectory( CurrentDirectory ); if( rc != ERR_NO_ERR ) { return( rc ); } } FileIOMessage( fn, lc, bc ); return( ERR_NO_ERR ); } /* SaveFile */
/* * InsertLines - insert a set of lines after specified number in current file */ vi_rc InsertLines( linenum s, fcb_list *fcblist, undo_stack *us ) { fcb *sfcb, *cfcb; linenum l, e; vi_rc rc; rc = ModificationTest(); if( rc != ERR_NO_ERR ) { return( rc ); } if( s < 0 ) { return( ERR_NO_SUCH_LINE ); } /* * find the number of lines inserted */ e = 0; for( cfcb = fcblist->head; cfcb != NULL; cfcb = cfcb->next ) { e += cfcb->end_line - cfcb->start_line + 1; } e += s; /* * see if there is a null fcb at the head; if so, ditch * the null fcb and then reset line ranges */ if( CurrentFile->fcbs.head->nullfcb ) { FreeEntireFcb( CurrentFile->fcbs.head ); CurrentFile->fcbs = *fcblist; e = e - s; s = 0; /* * if we are to insert after line 0, then make this block of * fcbs the first set in the text */ } else if( s == 0 ) { fcblist->tail->next = CurrentFile->fcbs.head; CurrentFile->fcbs.head->prev = fcblist->tail; CurrentFile->fcbs.head = fcblist->head; } else { /* * if we are inserting after the last fcb in the file, * make this block of fcbs the last set in the text */ rc = FindFcbWithLine( s + 1, CurrentFile, &sfcb ); if( rc != ERR_NO_ERR ) { if( rc != ERR_NO_SUCH_LINE ) { return( rc ); } fcblist->head->prev = CurrentFile->fcbs.tail; CurrentFile->fcbs.tail->next = fcblist->head; CurrentFile->fcbs.tail = fcblist->tail; /* * put the lines after the line to be have text inserted * into a new fcb, then insert the block of fcb's after * the fcb containing the line to have text inserted */ } else { rc = SplitFcbAtLine( s + 1, CurrentFile, sfcb ); if( rc > ERR_NO_ERR ) { return( rc ); } /* * line we want to split at is already the first line * in the fcb, so chain the new fcb block before * the fcb containg the line we want to split at */ if( rc == NO_SPLIT_CREATED_AT_START_LINE ) { if( sfcb->prev != NULL ) { sfcb->prev->next = fcblist->head; } fcblist->head->prev = sfcb->prev; sfcb->prev = fcblist->tail; fcblist->tail->next = sfcb; /* * chain the new fcb block after the fcb that used * to containing the line we wanted to split at, and * before the new fcb containing the line we want * to split at */ } else { if( rc == NO_SPLIT_CREATED_AT_END_LINE ) { // Die( "Impossible, can't be past last line"); } if( sfcb->next != NULL ) { sfcb->next->prev = fcblist->tail; } fcblist->tail->next = sfcb->next; sfcb->next = fcblist->head; fcblist->head->prev = sfcb; } } } /* * now, resequence line numbers and set proper file ptr */ for( cfcb = fcblist->head; cfcb != NULL; cfcb = cfcb->next ) { cfcb->f = CurrentFile; l = cfcb->end_line - cfcb->start_line; if( cfcb->prev != NULL ) { cfcb->start_line = cfcb->prev->end_line + 1; } else { cfcb->start_line = 1; } cfcb->end_line = cfcb->start_line + l; } /* * finish up: collect fcbs, point to corrent line, and * build undo for operation */ rc = MergeAllFcbs( &CurrentFile->fcbs ); if( rc != ERR_NO_ERR ) { return( rc ); } StartUndoGroup( us ); rc = ValidateCurrentLine(); if( rc != ERR_NO_ERR ) { return( rc ); } Modified( true ); UndoInsert( s + 1, e, us ); EndUndoGroup( us ); return( ERR_NO_ERR ); } /* InsertLines */