/* $begin mmfree */ void mm_free(void *bp) { size_t size = GET_SIZE(HDRP(bp)); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); insert_block(coalesce(bp)); }
static int read_block(t_app *app, char **array, unsigned int nbr) { unsigned int i; t_block *n; i = 0; if (!verif_number(array[1]) || !verif_number(array[2])) return (0); if (array[0][0] == '#' || array[0][0] == 'L') return (0); n = new_block(array[0], ft_atoi(array[1]), ft_atoi(array[2])); insert_block(app, n); if (app->read_mode == 1) { app->have_start = 1; app->in = nbr; } else if (app->read_mode == 2) { app->have_end = 1; app->out = nbr; } if (app->read_mode == 1 || app->read_mode == 2) app->read_mode = 0; return (1); }
void * LRMI_alloc_real(int size) { int i; char *r = (char *)REAL_MEM_BASE; if (!mem_info.ready) return NULL; if (mem_info.count == REAL_MEM_BLOCKS) return NULL; size = (size + 15) & ~15; for (i = 0; i < mem_info.count; i++) { if (mem_info.blocks[i].free && size < mem_info.blocks[i].size) { insert_block(i); mem_info.blocks[i].size = size; mem_info.blocks[i].free = 0; mem_info.blocks[i + 1].size -= size; return (void *)r; } r += mem_info.blocks[i].size; } return NULL; }
/* * Allocate a page and add it to freelist of given pool. */ static int grow_pool(struct xv_pool *pool, gfp_t flags) { struct page *page; struct block_header *block; page = alloc_page(flags); if (unlikely(!page)) return -ENOMEM; stat_inc(&pool->total_pages); spin_lock(&pool->lock); block = get_ptr_atomic(page, 0); block->size = PAGE_SIZE - XV_ALIGN; set_flag(block, BLOCK_FREE); clear_flag(block, PREV_FREE); set_blockprev(block, 0); insert_block(pool, page, 0, block); put_ptr_atomic(block); spin_unlock(&pool->lock); return 0; }
/* we add an element to the list of blocks, it is either added to an existing block or in a block specifically created if there was none */ static void insert_elem(tmp_block_t **block_list, unsigned abs_i, unsigned abs_j, float val, unsigned c, unsigned r) { /* we are looking for the block that contains (abs_i, abs_j) (abs = absolute) */ unsigned i,j; i = abs_i / c; j = abs_j / r; tmp_block_t *block; block = search_block(*block_list, i, j); if (!block) { /* the block does not exist yet */ /* create it */ block = create_block(c, r); block->i = i; block->j = j; //printf("create block %d %d !\n", i, j); /* insert it in the block list */ insert_block(block, block_list, i, j); } /* now insert the value in the corresponding block */ unsigned local_i, local_j, local_index; local_i = abs_i % c; local_j = abs_j % r; local_index = local_j * c + local_i; block->val[local_index] = val; }
/* * ShmemDynFree */ void ShmemDynFree(void *addr) { if (!ShmemDynAddrIsValid(addr)) elog(ERROR, "ShmemDynFree: invalid/double freeing (%p)", addr); insert_block(addr); }
//Draws the matrix void paint_matrix () { //Goes through matrix for( int i = 0; i < LC_MATRIX_HEIGHT; i++) for( int j = 0; j < LC_MATRIX_WIDTH; j++) { insert_block (j, i, game_matrix[i][j]); }//for }//paint_matrix
static void split_block(void *ptr, Size size) { Size orig_size = get_size(ptr); void *new_block = (void *) ((intptr_t) ptr + size + sizeof(Header)); Header *header = get_header(ptr); init_block(new_block, orig_size - size - sizeof(Header), false); insert_block(new_block); header->size = size; header->is_allocated = true; }
/* $begin mminit */ int mm_init(void) { /* create the initial empty heap */ if ((heap_listp = mem_sbrk(6*WSIZE)) == NULL) { return -1; } PUT(heap_listp, 0); /* alignment padding */ PUT(heap_listp+(1*WSIZE), PACK(OVERHEAD, 1)); /* prologue header */ PUT(heap_listp+(2*WSIZE), 0); PUT(heap_listp+(3*WSIZE), 0); PUT(heap_listp+(4*WSIZE), PACK(OVERHEAD, 1)); /* prologue footer */ PUT(heap_listp+(5*WSIZE), PACK(0, 1)); /* epilogue header */ heap_listp += (2*WSIZE); freeblockcount = 0; //mm_checkheap(1); char* freeblock; /* Extend the empty heap with a free block of CHUNKSIZE bytes */ if ((freeblock = extend_heap((CHUNKSIZE/WSIZE + 88))) == NULL) { return -1; } insert_block(freeblock); //mm_checkheap(1); /*printf("Remove-a block\n"); remove_block(freeblock); mm_checkheap(1);*/ /*char* anotherfree; anotherfree = extend_heap(CHUNKSIZE/WSIZE); printf("adda annari blokkinni\n"); insert_block(anotherfree);*/ /*char* temp; temp = extend_heap(CHUNKSIZE/WSIZE); printf("adda þriðju blokkinni\n"); insert_block(temp);*/ /*size_t predFirstBlock = GET(PRED(freeblock)); size_t succFirstBlock = GET((char*)SUCC(freeblock)); printf("FIRSTBLOCK, PRED: %x SUCC: %x\n", predFirstBlock, succFirstBlock); remove_block(freeblock); printf("Remove-a fremstu blokk\n"); mm_checkheap(1);*/ return 0; }
BLOCK_LIST * find_block_combo(BLOCK_LIST *list, BLOCK *block, BLOCK_LIST *combo) { BLOCK_LIST *ptr; if (list == NULL) { return NULL; } if (block == NULL) { return NULL; } ptr = list; // For all blocks while (ptr != NULL) { // If it is touching and if it is the same color if (neighbor_block(block, (BLOCK *)ptr->data) && ((BLOCK *)ptr->data)->image == block->image) { // If it is not in the list if (g_slist_find(combo, ptr->data) == NULL) { // Remove the block //blocks = remove_block(blocks, ptr); // Put it in the list combo = insert_block(combo, ptr->data); // Find combo blocks combo = find_block_combo(list, (BLOCK *)ptr->data, combo); } } ptr = ptr->next; } return combo; }
int QTextDocumentPrivate::insertBlock(const QChar &blockSeparator, int pos, int blockFormat, int charFormat, QTextUndoCommand::Operation op) { Q_ASSERT(formats.format(blockFormat).isBlockFormat()); Q_ASSERT(formats.format(charFormat).isCharFormat()); Q_ASSERT(pos >= 0 && (pos < fragments.length() || (pos == 0 && fragments.length() == 0))); Q_ASSERT(isValidBlockSeparator(blockSeparator)); beginEditBlock(); int strPos = text.length(); text.append(blockSeparator); const int fragment = insert_block(pos, strPos, charFormat, blockFormat, op, QTextUndoCommand::BlockRemoved); Q_ASSERT(blocks.length() == fragments.length()); int b = blocks.findNode(pos); QTextBlockData *B = blocks.fragment(b); QTextUndoCommand c = { QTextUndoCommand::BlockInserted, true, op, charFormat, strPos, pos, { blockFormat }, B->revision }; appendUndoItem(c); Q_ASSERT(undoState == undoStack.size()); // update revision numbers of the modified blocks. Close to the // truth, but we may want to special case breaking a block before // the first or behind the last character B->revision = undoState; b = blocks.next(b); if (b) { B = blocks.fragment(b); B->revision = undoState; } if (formats.charFormat(charFormat).objectIndex() == -1) needsEnsureMaximumBlockCount = true; endEditBlock(); return fragment; }
/* $begin mmplace-proto */ static void *place(void *bp, size_t asize) // $end mmplace-proto { size_t csize = GET_SIZE(HDRP(bp)); void *alloBlock = bp; if ((csize - asize) >= (DSIZE + OVERHEAD)) { PUT(HDRP(bp), PACK(asize, 1)); PUT(FTRP(bp), PACK(asize, 1)); bp = NEXT_BLKP(bp); PUT(HDRP(bp), PACK(csize-asize, 0)); PUT(FTRP(bp), PACK(csize-asize, 0)); // setjum free blokkina sem kom út úr splitti í free lista insert_block(bp); } else { PUT(HDRP(bp), PACK(csize, 1)); PUT(FTRP(bp), PACK(csize, 1)); } // skilum pointer á allocated blokkina return alloBlock; }
static vptr_t *find_free_blocks(uint32_t amount) { if(amount == 0) PANIC(); for(uint32_t i=0; i<metadata->blocks_allocated; ++i) { struct blockinfo *bi = &metadata->blocks[i]; if(!bi->reserved && bi->size >= amount) { if(amount < bi->size) { //kprintf("Splitting block %d %x, size: %d\n", i, bi->ptr, bi->size-amount); vptr_t *newptr = bi->ptr + ((bi->size - amount) * 0x1000); struct blockinfo *ret = insert_block(amount, newptr); ret->reserved=true; bi->size -= amount; return ret->ptr; } bi->reserved=true; return bi->ptr; } } return NULL; }
void *kmalloc(size_t size) { if(size==0) return NULL; if(!kheap_end) { kheap_end=(0xC0000000|kernel_end_addr)+0x1000; // Kernel heap starts where kernel code ends metadata=(struct metadata*)kalloc_page(kheap_end, true, true); metadata->blocks_allocated=0; metadata->max_blocks = (0x1000 - sizeof(struct metadata)) / sizeof(struct blockinfo); metadata->blocks = (struct blockinfo*)&metadata[1]; metadata->next=NULL; kheap_end += 0x1000; } int amount; if(size % 0x1000 == 0) amount=size/0x1000; else amount=(size/0x1000)+1; if(amount==0) amount=1; vptr_t *hole = find_free_blocks(amount); if(hole) { if((vaddr_t)hole & 0x00000FFF) PANIC(); return hole; } vptr_t* ret=NULL; for(int i=0; i<amount; ++i, kheap_end+=0x1000) { if(!ret) ret=kalloc_page(kheap_end, false, true); else kalloc_page(kheap_end, false, true); } struct blockinfo *bi=insert_block(amount, ret); bi->reserved=true; if((vaddr_t)ret & 0x00000FFF) PANIC(); return ret; }
/* * mm_realloc - naive implementation of mm_realloc. The realloc() function shall change the * size of the memory object pointed to by ptr to the size specified by size. The contents * of the object shall remain unchanged up to the lesser of the new and old sizes. If the * new size of the memory object would require movement of the object, the space for the * previous instantiation of the object is freed. If the new size is larger, the contents * of the newly allocated portion of the object are unspecified. */ void *mm_realloc(void *ptr, size_t size) { void *newp; void *oldp = ptr; size_t oldSize = GET_SIZE(HDRP(oldp)); //size_t newSize = ALIGN(size); size_t asize; //size_t isPrevFree = GET_ALLOC(FTRP(PREV_BLKP(oldp))); size_t isNextFree = GET_ALLOC(HDRP(NEXT_BLKP(oldp))); //size_t prevSize = GET_SIZE(FTRP(PREV_BLKP(oldp))); size_t nextSize = GET_SIZE(HDRP(NEXT_BLKP(oldp))); //mm_checkheap(0); if(ptr == NULL) return mm_malloc(size); else if(size == 0){ mm_free(ptr); return NULL; } else if(size == GET_SIZE(HDRP(ptr))) return ptr; if (size <= DSIZE) asize = DSIZE + OVERHEAD; else asize = DSIZE * ((size + (OVERHEAD) + (DSIZE-1)) / DSIZE); if(asize <= oldSize){ //printf("OldSize: %zu , asize: %zu\n", oldSize, asize); if(oldSize - asize < OVERHEAD){ //printf("FER HINGAÐ\n"); return oldp; } PUT(HDRP(oldp), PACK(asize, 1)); PUT(FTRP(oldp), PACK(asize, 1)); //printf("alloc minnkar og nýtir rest í fría blokk\n"); PUT(HDRP(NEXT_BLKP(oldp)), PACK(oldSize - asize, 0)); PUT(FTRP(NEXT_BLKP(oldp)), PACK(oldSize - asize, 0)); insert_block(NEXT_BLKP(oldp)); } /*else if(!isNextFree && (oldSize + nextSize) >= asize){ if((oldSize + nextSize) - asize < OVERHEAD){ PUT(HDRP(oldp), PACK(oldSize + nextSize, 1)); PUT(FTRP(oldp), PACK(oldSize + nextSize, 1)); } else{ PUT(HDRP(oldp), PACK(asize, 1)); PUT(FTRP(oldp), PACK(asize, 1)); PUT(HDRP(NEXT_BLKP(oldp)), PACK((oldSize+nextSize)-asize, 0)); PUT(FTRP(NEXT_BLKP(oldp)), PACK((oldSize+nextSize)-asize, 0)); void *freeBlock = NEXT_BLKP(oldp); insert_block(freeBlock); return oldp; } }*/ // calculate the adjusted size of the request ???? // ef adjustedSize <= oldsize, return ptr if ((newp = mm_malloc(size)) == NULL) { printf("ERROR: mm_malloc failed in mm_realloc\n"); exit(1); } if (size < oldSize) { oldSize = size; } memcpy(newp, ptr, oldSize); mm_free(ptr); return newp; }
/* * Free block identified with <page, offset> */ void xv_free(struct xv_pool *pool, struct page *page, u32 offset) { void *page_start; struct block_header *block, *tmpblock; offset -= XV_ALIGN; spin_lock(&pool->lock); page_start = get_ptr_atomic(page, 0); block = (struct block_header *)((char *)page_start + offset); /* Catch double free bugs */ BUG_ON(test_flag(block, BLOCK_FREE)); block->size = ALIGN(block->size, XV_ALIGN); tmpblock = BLOCK_NEXT(block); if (offset + block->size + XV_ALIGN == PAGE_SIZE) tmpblock = NULL; /* Merge next block if its free */ if (tmpblock && test_flag(tmpblock, BLOCK_FREE)) { /* * Blocks smaller than XV_MIN_ALLOC_SIZE * are not inserted in any free list. */ if (tmpblock->size >= XV_MIN_ALLOC_SIZE) { remove_block(pool, page, offset + block->size + XV_ALIGN, tmpblock, get_index_for_insert(tmpblock->size)); } block->size += tmpblock->size + XV_ALIGN; } /* Merge previous block if its free */ if (test_flag(block, PREV_FREE)) { tmpblock = (struct block_header *)((char *)(page_start) + get_blockprev(block)); offset = offset - tmpblock->size - XV_ALIGN; if (tmpblock->size >= XV_MIN_ALLOC_SIZE) remove_block(pool, page, offset, tmpblock, get_index_for_insert(tmpblock->size)); tmpblock->size += block->size + XV_ALIGN; block = tmpblock; } /* No used objects in this page. Free it. */ if (block->size == PAGE_SIZE - XV_ALIGN) { put_ptr_atomic(page_start); spin_unlock(&pool->lock); __free_page(page); stat_dec(&pool->total_pages); return; } set_flag(block, BLOCK_FREE); if (block->size >= XV_MIN_ALLOC_SIZE) insert_block(pool, page, offset, block); if (offset + block->size + XV_ALIGN != PAGE_SIZE) { tmpblock = BLOCK_NEXT(block); set_flag(tmpblock, PREV_FREE); set_blockprev(tmpblock, offset); } put_ptr_atomic(page_start); spin_unlock(&pool->lock); }
/** * xv_malloc - Allocate block of given size from pool. * @pool: pool to allocate from * @size: size of block to allocate * @page: page no. that holds the object * @offset: location of object within page * * On success, <page, offset> identifies block allocated * and 0 is returned. On failure, <page, offset> is set to * 0 and -ENOMEM is returned. * * Allocation requests with size > XV_MAX_ALLOC_SIZE will fail. */ int xv_malloc(struct xv_pool *pool, u32 size, struct page **page, u32 *offset, gfp_t flags) { int error; u32 index, tmpsize, origsize, tmpoffset; struct block_header *block, *tmpblock; *page = NULL; *offset = 0; origsize = size; if (unlikely(!size || size > XV_MAX_ALLOC_SIZE)) return -ENOMEM; size = ALIGN(size, XV_ALIGN); spin_lock(&pool->lock); index = find_block(pool, size, page, offset); if (!*page) { spin_unlock(&pool->lock); if (flags & GFP_NOWAIT) return -ENOMEM; error = grow_pool(pool, flags); if (unlikely(error)) return error; spin_lock(&pool->lock); index = find_block(pool, size, page, offset); } if (!*page) { spin_unlock(&pool->lock); return -ENOMEM; } block = get_ptr_atomic(*page, *offset); remove_block(pool, *page, *offset, block, index); /* Split the block if required */ tmpoffset = *offset + size + XV_ALIGN; tmpsize = block->size - size; tmpblock = (struct block_header *)((char *)block + size + XV_ALIGN); if (tmpsize) { tmpblock->size = tmpsize - XV_ALIGN; set_flag(tmpblock, BLOCK_FREE); clear_flag(tmpblock, PREV_FREE); set_blockprev(tmpblock, *offset); if (tmpblock->size >= XV_MIN_ALLOC_SIZE) insert_block(pool, *page, tmpoffset, tmpblock); if (tmpoffset + XV_ALIGN + tmpblock->size != PAGE_SIZE) { tmpblock = BLOCK_NEXT(tmpblock); set_blockprev(tmpblock, tmpoffset); } } else { /* This block is exact fit */ if (tmpoffset != PAGE_SIZE) clear_flag(tmpblock, PREV_FREE); } block->size = origsize; clear_flag(block, BLOCK_FREE); put_ptr_atomic(block); spin_unlock(&pool->lock); *offset += XV_ALIGN; return 0; }
void QTextDocumentPrivate::move(int pos, int to, int length, QTextUndoCommand::Operation op) { Q_ASSERT(to <= fragments.length() && to <= pos); Q_ASSERT(pos >= 0 && pos+length <= fragments.length()); Q_ASSERT(blocks.length() == fragments.length()); if (pos == to) return; const bool needsInsert = to != -1; #if !defined(QT_NO_DEBUG) const bool startAndEndInSameFrame = (frameAt(pos) == frameAt(pos + length - 1)); const bool endIsEndOfChildFrame = (isAncestorFrame(frameAt(pos), frameAt(pos + length - 1)) && text.at(find(pos + length - 1)->stringPosition) == QTextEndOfFrame); const bool startIsStartOfFrameAndEndIsEndOfFrameWithCommonParent = (text.at(find(pos)->stringPosition) == QTextBeginningOfFrame && text.at(find(pos + length - 1)->stringPosition) == QTextEndOfFrame && frameAt(pos)->parentFrame() == frameAt(pos + length - 1)->parentFrame()); const bool isFirstTableCell = (qobject_cast<QTextTable *>(frameAt(pos + length - 1)) && frameAt(pos + length - 1)->parentFrame() == frameAt(pos)); Q_ASSERT(startAndEndInSameFrame || endIsEndOfChildFrame || startIsStartOfFrameAndEndIsEndOfFrameWithCommonParent || isFirstTableCell); #endif beginEditBlock(); split(pos); split(pos+length); uint dst = needsInsert ? fragments.findNode(to) : 0; uint dstKey = needsInsert ? fragments.position(dst) : 0; uint x = fragments.findNode(pos); uint end = fragments.findNode(pos+length); uint w = 0; while (x != end) { uint n = fragments.next(x); uint key = fragments.position(x); uint b = blocks.findNode(key+1); QTextBlockData *B = blocks.fragment(b); int blockRevision = B->revision; QTextFragmentData *X = fragments.fragment(x); QTextUndoCommand c = { QTextUndoCommand::Removed, true, op, X->format, X->stringPosition, key, { X->size }, blockRevision }; QTextUndoCommand cInsert = { QTextUndoCommand::Inserted, true, op, X->format, X->stringPosition, dstKey, { X->size }, blockRevision }; if (key+1 != blocks.position(b)) { // qDebug("remove_string from %d length %d", key, X->size); Q_ASSERT(noBlockInString(text.mid(X->stringPosition, X->size))); w = remove_string(key, X->size, op); if (needsInsert) { insert_string(dstKey, X->stringPosition, X->size, X->format, op); dstKey += X->size; } } else { // qDebug("remove_block at %d", key); Q_ASSERT(X->size == 1 && isValidBlockSeparator(text.at(X->stringPosition))); b = blocks.previous(b); B = 0; c.command = blocks.size(b) == 1 ? QTextUndoCommand::BlockDeleted : QTextUndoCommand::BlockRemoved; w = remove_block(key, &c.blockFormat, QTextUndoCommand::BlockAdded, op); if (needsInsert) { insert_block(dstKey++, X->stringPosition, X->format, c.blockFormat, op, QTextUndoCommand::BlockRemoved); cInsert.command = blocks.size(b) == 1 ? QTextUndoCommand::BlockAdded : QTextUndoCommand::BlockInserted; cInsert.blockFormat = c.blockFormat; } } appendUndoItem(c); if (B) B->revision = undoState; x = n; if (needsInsert) appendUndoItem(cInsert); } if (w) unite(w); Q_ASSERT(blocks.length() == fragments.length()); endEditBlock(); }
int QTextDocumentPrivate::undoRedo(bool undo) { PMDEBUG("%s, undoState=%d, undoStack size=%d", undo ? "undo:" : "redo:", undoState, undoStack.size()); if (!undoEnabled || (undo && undoState == 0) || (!undo && undoState == undoStack.size())) return -1; undoEnabled = false; beginEditBlock(); while (1) { if (undo) --undoState; QTextUndoCommand &c = undoStack[undoState]; int resetBlockRevision = c.pos; switch(c.command) { case QTextUndoCommand::Inserted: remove(c.pos, c.length, (QTextUndoCommand::Operation)c.operation); PMDEBUG(" erase: from %d, length %d", c.pos, c.length); c.command = QTextUndoCommand::Removed; break; case QTextUndoCommand::Removed: PMDEBUG(" insert: format %d (from %d, length %d, strpos=%d)", c.format, c.pos, c.length, c.strPos); insert_string(c.pos, c.strPos, c.length, c.format, (QTextUndoCommand::Operation)c.operation); c.command = QTextUndoCommand::Inserted; break; case QTextUndoCommand::BlockInserted: case QTextUndoCommand::BlockAdded: remove_block(c.pos, &c.blockFormat, c.command, (QTextUndoCommand::Operation)c.operation); PMDEBUG(" blockremove: from %d", c.pos); if (c.command == QTextUndoCommand::BlockInserted) c.command = QTextUndoCommand::BlockRemoved; else c.command = QTextUndoCommand::BlockDeleted; break; case QTextUndoCommand::BlockRemoved: case QTextUndoCommand::BlockDeleted: PMDEBUG(" blockinsert: charformat %d blockformat %d (pos %d, strpos=%d)", c.format, c.blockFormat, c.pos, c.strPos); insert_block(c.pos, c.strPos, c.format, c.blockFormat, (QTextUndoCommand::Operation)c.operation, c.command); resetBlockRevision += 1; if (c.command == QTextUndoCommand::BlockRemoved) c.command = QTextUndoCommand::BlockInserted; else c.command = QTextUndoCommand::BlockAdded; break; case QTextUndoCommand::CharFormatChanged: { resetBlockRevision = -1; // ## TODO PMDEBUG(" charFormat: format %d (from %d, length %d)", c.format, c.pos, c.length); FragmentIterator it = find(c.pos); Q_ASSERT(!it.atEnd()); int oldFormat = it.value()->format; setCharFormat(c.pos, c.length, formats.charFormat(c.format)); c.format = oldFormat; break; } case QTextUndoCommand::BlockFormatChanged: { resetBlockRevision = -1; // ## TODO PMDEBUG(" blockformat: format %d pos %d", c.format, c.pos); QTextBlock it = blocksFind(c.pos); Q_ASSERT(it.isValid()); int oldFormat = block(it)->format; block(it)->format = c.format; QTextBlockGroup *oldGroup = qobject_cast<QTextBlockGroup *>(objectForFormat(formats.blockFormat(oldFormat))); QTextBlockGroup *group = qobject_cast<QTextBlockGroup *>(objectForFormat(formats.blockFormat(c.format))); c.format = oldFormat; if (group != oldGroup) { if (oldGroup) oldGroup->blockRemoved(it); if (group) group->blockInserted(it); } else if (group) { group->blockFormatChanged(it); } documentChange(it.position(), it.length()); break; } case QTextUndoCommand::GroupFormatChange: { resetBlockRevision = -1; // ## TODO PMDEBUG(" group format change"); QTextObject *object = objectForIndex(c.objectIndex); int oldFormat = formats.objectFormatIndex(c.objectIndex); changeObjectFormat(object, c.format); c.format = oldFormat; break; } case QTextUndoCommand::Custom: resetBlockRevision = -1; // ## TODO if (undo) c.custom->undo(); else c.custom->redo(); break; default: Q_ASSERT(false); } if (resetBlockRevision >= 0) { int b = blocks.findNode(resetBlockRevision); QTextBlockData *B = blocks.fragment(b); B->revision = c.revision; } if (undo) { if (undoState == 0 || !undoStack[undoState-1].block) break; } else { ++undoState; if (undoState == undoStack.size() || !undoStack[undoState-1].block) break; } } undoEnabled = true; int editPos = -1; if (docChangeFrom >= 0) { editPos = qMin(docChangeFrom + docChangeLength, length() - 1); } endEditBlock(); emitUndoAvailable(isUndoAvailable()); emitRedoAvailable(isRedoAvailable()); return editPos; }