/****************************************************************************** * ME_CheckCharOffsets * * Checks if editor lists' validity and optionally dumps the document structure */ void ME_CheckCharOffsets(ME_TextEditor *editor) { ME_DisplayItem *p = editor->pBuffer->pFirst; int ofs = 0, ofsp = 0; TRACE_(richedit_check)("Checking begin\n"); if(TRACE_ON(richedit_lists)) { TRACE_(richedit_lists)("---\n"); ME_DumpDocument(editor->pBuffer); } do { p = ME_FindItemFwd(p, diRunOrParagraphOrEnd); switch(p->type) { case diTextEnd: TRACE_(richedit_check)("tend, real ofsp = %d, counted = %d\n", p->member.para.nCharOfs, ofsp+ofs); assert(ofsp+ofs == p->member.para.nCharOfs); TRACE_(richedit_check)("Checking finished\n"); return; case diParagraph: TRACE_(richedit_check)("para, real ofsp = %d, counted = %d\n", p->member.para.nCharOfs, ofsp+ofs); assert(ofsp+ofs == p->member.para.nCharOfs); ofsp = p->member.para.nCharOfs; ofs = 0; break; case diRun: TRACE_(richedit_check)("run, real ofs = %d (+ofsp = %d), counted = %d, len = %d, txt = %s, flags=%08x, fx&mask = %08x\n", p->member.run.nCharOfs, p->member.run.nCharOfs+ofsp, ofsp+ofs, p->member.run.len, debugstr_run( &p->member.run ), p->member.run.nFlags, p->member.run.style->fmt.dwMask & p->member.run.style->fmt.dwEffects); assert(ofs == p->member.run.nCharOfs); assert(p->member.run.len); ofs += p->member.run.len; break; case diCell: TRACE_(richedit_check)("cell\n"); break; default: assert(0); } } while(1); TRACE_(richedit_check)("Checking finished\n"); }
/* Make a bunch of assertions to make sure tables haven't been corrupted. * * These invariants may not hold true in the middle of streaming in rich text * or during an undo and redo of streaming in rich text. It should be safe to * call this method after an event is processed. */ void ME_CheckTablesForCorruption(ME_TextEditor *editor) { if(TRACE_ON(richedit_lists)) { TRACE("---\n"); ME_DumpDocument(editor->pBuffer); } #ifndef NDEBUG { ME_DisplayItem *p, *pPrev; pPrev = editor->pBuffer->pFirst; p = pPrev->next; if (!editor->bEmulateVersion10) /* v4.1 */ { while (p->type == diParagraph) { assert(p->member.para.pFmt->dwMask & PFM_TABLE); assert(p->member.para.pFmt->dwMask & PFM_TABLEROWDELIMITER); if (p->member.para.pCell) { assert(p->member.para.nFlags & MEPF_CELL); assert(p->member.para.pFmt->wEffects & PFE_TABLE); } if (p->member.para.pCell != pPrev->member.para.pCell) { /* There must be a diCell in between the paragraphs if pCell changes. */ ME_DisplayItem *pCell = ME_FindItemBack(p, diCell); assert(pCell); assert(ME_FindItemBack(p, diRun) == ME_FindItemBack(pCell, diRun)); } if (p->member.para.nFlags & MEPF_ROWEND) { /* ROWEND must come after a cell. */ assert(pPrev->member.para.pCell); assert(p->member.para.pCell == pPrev->member.para.pCell->member.cell.parent_cell); assert(p->member.para.pFmt->wEffects & PFE_TABLEROWDELIMITER); } else if (p->member.para.pCell) { assert(!(p->member.para.pFmt->wEffects & PFE_TABLEROWDELIMITER)); assert(pPrev->member.para.pCell || pPrev->member.para.nFlags & MEPF_ROWSTART); if (pPrev->member.para.pCell && !(pPrev->member.para.nFlags & MEPF_ROWSTART)) { assert(p->member.para.pCell->member.cell.parent_cell == pPrev->member.para.pCell->member.cell.parent_cell); if (pPrev->member.para.pCell != p->member.para.pCell) assert(pPrev->member.para.pCell == p->member.para.pCell->member.cell.prev_cell); } } else if (!(p->member.para.nFlags & MEPF_ROWSTART)) { assert(!(p->member.para.pFmt->wEffects & PFE_TABLEROWDELIMITER)); /* ROWSTART must be followed by a cell. */ assert(!(p->member.para.nFlags & MEPF_CELL)); /* ROWSTART must be followed by a cell. */ assert(!(pPrev->member.para.nFlags & MEPF_ROWSTART)); } pPrev = p; p = p->member.para.next_para; } } else { /* v1.0 - 3.0 */ while (p->type == diParagraph) { assert(!(p->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND|MEPF_CELL))); assert(p->member.para.pFmt->dwMask & PFM_TABLE); assert(!(p->member.para.pFmt->wEffects & PFM_TABLEROWDELIMITER)); assert(!p->member.para.pCell); p = p->member.para.next_para; } return; } assert(p->type == diTextEnd); assert(!pPrev->member.para.pCell); } #endif }