/* * freeSavebuf - release savebuf data */ static void freeSavebuf( savebuf *tmp ) { fcb *cfcb, *tfcb; switch( tmp->type ) { case SAVEBUF_NOP: break; case SAVEBUF_LINE: MemFree( tmp->u.data ); break; case SAVEBUF_FCBS: for( cfcb = tmp->u.fcbs.head; cfcb != NULL; cfcb = tfcb ) { tfcb = cfcb->next; FreeEntireFcb( cfcb ); } break; } } /* freeSavebuf */
/* * 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 */