Commit 2223014d authored by Dimitrie O. Paun's avatar Dimitrie O. Paun Committed by Alexandre Julliard

Assert on inconsistent range list states.

Various code cleanups, few potential bugs fixed.
parent 074e2b4c
...@@ -949,11 +949,6 @@ static BOOL iterator_frameditems(ITERATOR* i, LISTVIEW_INFO* infoPtr, const RECT ...@@ -949,11 +949,6 @@ static BOOL iterator_frameditems(ITERATOR* i, LISTVIEW_INFO* infoPtr, const RECT
if (IntersectRect(&rcTemp, &rcItem, &frame)) if (IntersectRect(&rcTemp, &rcItem, &frame))
ranges_additem(i->ranges, nItem); ranges_additem(i->ranges, nItem);
} }
if (TRACE_ON(listview))
{
TRACE(" icon items:\n");
ranges_dump(i->ranges);
}
return TRUE; return TRUE;
} }
else if (uView == LVS_REPORT) else if (uView == LVS_REPORT)
...@@ -2222,27 +2217,28 @@ static INT CALLBACK ranges_cmp(LPVOID range1, LPVOID range2, LPARAM flags) ...@@ -2222,27 +2217,28 @@ static INT CALLBACK ranges_cmp(LPVOID range1, LPVOID range2, LPARAM flags)
} }
#if DEBUG_RANGES #if DEBUG_RANGES
#define ranges_check ranges_assert #define ranges_check(ranges, desc) ranges_assert(ranges, desc, __FUNCTION__, __LINE__)
#else #else
#define ranges_check(ranges, desc) do { } while(0) #define ranges_check(ranges, desc) do { } while(0)
#endif #endif
static void ranges_assert(RANGES ranges, LPCSTR desc) static void ranges_assert(RANGES ranges, LPCSTR desc, const char *func, int line)
{ {
INT i; INT i;
RANGE *prev, *curr; RANGE *prev, *curr;
TRACE("*** Checking %s:%d:%s ***\n", func, line, desc);
assert (ranges); assert (ranges);
assert (ranges->hdpa->nItemCount >= 0); assert (ranges->hdpa->nItemCount >= 0);
if (ranges->hdpa->nItemCount == 0) return;
TRACE("*** Checking %s ***\n", desc);
ranges_dump(ranges); ranges_dump(ranges);
assert ((prev = (RANGE *)DPA_GetPtr(ranges->hdpa, 0))->lower >= 0); prev = (RANGE *)DPA_GetPtr(ranges->hdpa, 0);
/* assert (((RANGE *)DPA_GetPtr(ranges->hdpa, ranges->hdpa->nItemCount - 1))->upper <= nUpper); */ if (ranges->hdpa->nItemCount > 0)
assert (prev->lower >= 0 && prev->lower < prev->upper);
for (i = 1; i < ranges->hdpa->nItemCount; i++) for (i = 1; i < ranges->hdpa->nItemCount; i++)
{ {
curr = (RANGE *)DPA_GetPtr(ranges->hdpa, i); curr = (RANGE *)DPA_GetPtr(ranges->hdpa, i);
assert (prev->upper <= curr->lower); assert (prev->upper <= curr->lower);
assert (curr->lower < curr->upper);
prev = curr; prev = curr;
} }
TRACE("--- Done checking---\n"); TRACE("--- Done checking---\n");
...@@ -2260,8 +2256,7 @@ static RANGES ranges_create(int count) ...@@ -2260,8 +2256,7 @@ static RANGES ranges_create(int count)
static void ranges_destroy(RANGES ranges) static void ranges_destroy(RANGES ranges)
{ {
if (!ranges) return; if (ranges && ranges->hdpa)
if (ranges->hdpa)
{ {
INT i; INT i;
...@@ -2278,30 +2273,27 @@ static RANGES ranges_clone(RANGES ranges) ...@@ -2278,30 +2273,27 @@ static RANGES ranges_clone(RANGES ranges)
RANGES clone; RANGES clone;
INT i; INT i;
if (!ranges) return NULL; if (!(clone = ranges_create(ranges->hdpa->nItemCount))) goto fail;
clone = ranges_create(ranges->hdpa->nItemCount);
if (!clone) return NULL;
for (i = 0; i < ranges->hdpa->nItemCount; i++) for (i = 0; i < ranges->hdpa->nItemCount; i++)
{ {
RANGE *newrng = (RANGE *)COMCTL32_Alloc(sizeof(RANGE)); RANGE *newrng = (RANGE *)COMCTL32_Alloc(sizeof(RANGE));
if (!newrng) if (!newrng) goto fail;
{
ranges_destroy(clone);
return NULL;
}
*newrng = *((RANGE*)DPA_GetPtr(ranges->hdpa, i)); *newrng = *((RANGE*)DPA_GetPtr(ranges->hdpa, i));
DPA_InsertPtr(clone->hdpa, i, newrng); DPA_InsertPtr(clone->hdpa, i, newrng);
} }
return clone; return clone;
fail:
TRACE ("clone failed\n");
if (clone) ranges_destroy(clone);
return NULL;
} }
static RANGES ranges_diff(RANGES ranges, RANGES sub) static RANGES ranges_diff(RANGES ranges, RANGES sub)
{ {
INT i; INT i;
if (!ranges || !sub) return ranges;
for (i = 0; i < sub->hdpa->nItemCount; i++) for (i = 0; i < sub->hdpa->nItemCount; i++)
ranges_del(ranges, *((RANGE *)DPA_GetPtr(sub->hdpa, i))); ranges_del(ranges, *((RANGE *)DPA_GetPtr(sub->hdpa, i)));
...@@ -2312,7 +2304,6 @@ static void ranges_dump(RANGES ranges) ...@@ -2312,7 +2304,6 @@ static void ranges_dump(RANGES ranges)
{ {
INT i; INT i;
if (!ranges) return;
for (i = 0; i < ranges->hdpa->nItemCount; i++) for (i = 0; i < ranges->hdpa->nItemCount; i++)
TRACE(" %s\n", debugrange(DPA_GetPtr(ranges->hdpa, i))); TRACE(" %s\n", debugrange(DPA_GetPtr(ranges->hdpa, i)));
} }
...@@ -2322,8 +2313,6 @@ static inline BOOL ranges_contain(RANGES ranges, INT nItem) ...@@ -2322,8 +2313,6 @@ static inline BOOL ranges_contain(RANGES ranges, INT nItem)
RANGE srchrng = { nItem, nItem + 1 }; RANGE srchrng = { nItem, nItem + 1 };
TRACE("(nItem=%d)\n", nItem); TRACE("(nItem=%d)\n", nItem);
if (!ranges) return FALSE;
if (TRACE_ON(listview)) ranges_dump(ranges);
ranges_check(ranges, "before contain"); ranges_check(ranges, "before contain");
return DPA_Search(ranges->hdpa, &srchrng, 0, ranges_cmp, 0, DPAS_SORTED) != -1; return DPA_Search(ranges->hdpa, &srchrng, 0, ranges_cmp, 0, DPAS_SORTED) != -1;
} }
...@@ -2332,7 +2321,6 @@ static INT ranges_itemcount(RANGES ranges) ...@@ -2332,7 +2321,6 @@ static INT ranges_itemcount(RANGES ranges)
{ {
INT i, count = 0; INT i, count = 0;
if (!ranges) return 0;
for (i = 0; i < ranges->hdpa->nItemCount; i++) for (i = 0; i < ranges->hdpa->nItemCount; i++)
{ {
RANGE *sel = DPA_GetPtr(ranges->hdpa, i); RANGE *sel = DPA_GetPtr(ranges->hdpa, i);
...@@ -2347,11 +2335,10 @@ static BOOL ranges_shift(RANGES ranges, INT nItem, INT delta, INT nUpper) ...@@ -2347,11 +2335,10 @@ static BOOL ranges_shift(RANGES ranges, INT nItem, INT delta, INT nUpper)
RANGE srchrng = { nItem, nItem + 1 }, *chkrng; RANGE srchrng = { nItem, nItem + 1 }, *chkrng;
INT index; INT index;
if (!ranges) return FALSE;
index = DPA_Search(ranges->hdpa, &srchrng, 0, ranges_cmp, 0, DPAS_SORTED | DPAS_INSERTAFTER); index = DPA_Search(ranges->hdpa, &srchrng, 0, ranges_cmp, 0, DPAS_SORTED | DPAS_INSERTAFTER);
if (index == -1) return TRUE; if (index == -1) return TRUE;
for (;index < ranges->hdpa->nItemCount; index++) for (; index < ranges->hdpa->nItemCount; index++)
{ {
chkrng = DPA_GetPtr(ranges->hdpa, index); chkrng = DPA_GetPtr(ranges->hdpa, index);
if (chkrng->lower >= nItem) if (chkrng->lower >= nItem)
...@@ -2369,7 +2356,6 @@ static BOOL ranges_add(RANGES ranges, RANGE range) ...@@ -2369,7 +2356,6 @@ static BOOL ranges_add(RANGES ranges, RANGE range)
TRACE("(%s)\n", debugrange(&range)); TRACE("(%s)\n", debugrange(&range));
ranges_check(ranges, "before add"); ranges_check(ranges, "before add");
if (!ranges) goto fail;
/* try find overlapping regions first */ /* try find overlapping regions first */
srchrgn.lower = range.lower - 1; srchrgn.lower = range.lower - 1;
...@@ -2393,7 +2379,11 @@ static BOOL ranges_add(RANGES ranges, RANGE range) ...@@ -2393,7 +2379,11 @@ static BOOL ranges_add(RANGES ranges, RANGE range)
if (index == -1) index = 0; if (index == -1) index = 0;
/* and get it over with */ /* and get it over with */
DPA_InsertPtr(ranges->hdpa, index, newrgn); if (DPA_InsertPtr(ranges->hdpa, index, newrgn) == -1)
{
COMCTL32_Free(newrgn);
goto fail;
}
} }
else else
{ {
...@@ -2401,7 +2391,6 @@ static BOOL ranges_add(RANGES ranges, RANGE range) ...@@ -2401,7 +2391,6 @@ static BOOL ranges_add(RANGES ranges, RANGE range)
INT fromindex, mergeindex; INT fromindex, mergeindex;
chkrgn = DPA_GetPtr(ranges->hdpa, index); chkrgn = DPA_GetPtr(ranges->hdpa, index);
if (!chkrgn) goto fail;
TRACE("Merge with %s @%d\n", debugrange(chkrgn), index); TRACE("Merge with %s @%d\n", debugrange(chkrgn), index);
chkrgn->lower = min(range.lower, chkrgn->lower); chkrgn->lower = min(range.lower, chkrgn->lower);
...@@ -2427,8 +2416,6 @@ static BOOL ranges_add(RANGES ranges, RANGE range) ...@@ -2427,8 +2416,6 @@ static BOOL ranges_add(RANGES ranges, RANGE range)
TRACE("Merge with index %i\n", mergeindex); TRACE("Merge with index %i\n", mergeindex);
mrgrgn = DPA_GetPtr(ranges->hdpa, mergeindex); mrgrgn = DPA_GetPtr(ranges->hdpa, mergeindex);
if (!mrgrgn) goto fail;
chkrgn->lower = min(chkrgn->lower, mrgrgn->lower); chkrgn->lower = min(chkrgn->lower, mrgrgn->lower);
chkrgn->upper = max(chkrgn->upper, mrgrgn->upper); chkrgn->upper = max(chkrgn->upper, mrgrgn->upper);
COMCTL32_Free(mrgrgn); COMCTL32_Free(mrgrgn);
...@@ -2438,7 +2425,6 @@ static BOOL ranges_add(RANGES ranges, RANGE range) ...@@ -2438,7 +2425,6 @@ static BOOL ranges_add(RANGES ranges, RANGE range)
} }
ranges_check(ranges, "after add"); ranges_check(ranges, "after add");
if (TRACE_ON(listview)) ranges_dump(ranges);
return TRUE; return TRUE;
fail: fail:
...@@ -2453,7 +2439,6 @@ static BOOL ranges_del(RANGES ranges, RANGE range) ...@@ -2453,7 +2439,6 @@ static BOOL ranges_del(RANGES ranges, RANGE range)
TRACE("(%s)\n", debugrange(&range)); TRACE("(%s)\n", debugrange(&range));
ranges_check(ranges, "before del"); ranges_check(ranges, "before del");
if (!ranges) goto fail;
/* we don't use DPAS_SORTED here, since we need * /* we don't use DPAS_SORTED here, since we need *
* to find the first overlapping range */ * to find the first overlapping range */
...@@ -2461,7 +2446,6 @@ static BOOL ranges_del(RANGES ranges, RANGE range) ...@@ -2461,7 +2446,6 @@ static BOOL ranges_del(RANGES ranges, RANGE range)
while(index != -1) while(index != -1)
{ {
chkrgn = DPA_GetPtr(ranges->hdpa, index); chkrgn = DPA_GetPtr(ranges->hdpa, index);
if (!chkrgn) goto fail;
TRACE("Matches range %s @%d\n", debugrange(chkrgn), index); TRACE("Matches range %s @%d\n", debugrange(chkrgn), index);
...@@ -2500,7 +2484,11 @@ static BOOL ranges_del(RANGES ranges, RANGE range) ...@@ -2500,7 +2484,11 @@ static BOOL ranges_del(RANGES ranges, RANGE range)
newrgn->lower = chkrgn->lower; newrgn->lower = chkrgn->lower;
newrgn->upper = range.lower; newrgn->upper = range.lower;
chkrgn->lower = range.upper; chkrgn->lower = range.upper;
DPA_InsertPtr(ranges->hdpa, index, newrgn); if (DPA_InsertPtr(ranges->hdpa, index, newrgn) == -1)
{
COMCTL32_Free(newrgn);
goto fail;
}
chkrgn = &tmprgn; chkrgn = &tmprgn;
break; break;
} }
...@@ -2532,15 +2520,16 @@ static BOOL LISTVIEW_DeselectAllSkipItems(LISTVIEW_INFO *infoPtr, RANGES toSkip) ...@@ -2532,15 +2520,16 @@ static BOOL LISTVIEW_DeselectAllSkipItems(LISTVIEW_INFO *infoPtr, RANGES toSkip)
{ {
LVITEMW lvItem; LVITEMW lvItem;
ITERATOR i; ITERATOR i;
RANGES clone;
TRACE("()\n"); TRACE("()\n");
if (TRACE_ON(listview)) ranges_dump(toSkip);
lvItem.state = 0; lvItem.state = 0;
lvItem.stateMask = LVIS_SELECTED; lvItem.stateMask = LVIS_SELECTED;
/* need to clone the DPA because callbacks can change it */ /* need to clone the DPA because callbacks can change it */
iterator_ranges(&i, ranges_diff(ranges_clone(infoPtr->selectionRanges), toSkip)); if (!(clone = ranges_clone(infoPtr->selectionRanges))) return FALSE;
iterator_ranges(&i, ranges_diff(clone, toSkip));
while(iterator_next(&i)) while(iterator_next(&i))
LISTVIEW_SetItemState(infoPtr, i.nItem, &lvItem); LISTVIEW_SetItemState(infoPtr, i.nItem, &lvItem);
/* note that the iterator destructor will free the cloned range */ /* note that the iterator destructor will free the cloned range */
...@@ -2551,9 +2540,9 @@ static BOOL LISTVIEW_DeselectAllSkipItems(LISTVIEW_INFO *infoPtr, RANGES toSkip) ...@@ -2551,9 +2540,9 @@ static BOOL LISTVIEW_DeselectAllSkipItems(LISTVIEW_INFO *infoPtr, RANGES toSkip)
static inline BOOL LISTVIEW_DeselectAllSkipItem(LISTVIEW_INFO *infoPtr, INT nItem) static inline BOOL LISTVIEW_DeselectAllSkipItem(LISTVIEW_INFO *infoPtr, INT nItem)
{ {
RANGES toSkip = ranges_create(1); RANGES toSkip;
if (!toSkip) return FALSE; if (!(toSkip = ranges_create(1))) return FALSE;
if (nItem != -1) ranges_additem(toSkip, nItem); if (nItem != -1) ranges_additem(toSkip, nItem);
LISTVIEW_DeselectAllSkipItems(infoPtr, toSkip); LISTVIEW_DeselectAllSkipItems(infoPtr, toSkip);
ranges_destroy(toSkip); ranges_destroy(toSkip);
...@@ -6878,6 +6867,9 @@ static LRESULT LISTVIEW_Create(HWND hwnd, LPCREATESTRUCTW lpcs) ...@@ -6878,6 +6867,9 @@ static LRESULT LISTVIEW_Create(HWND hwnd, LPCREATESTRUCTW lpcs)
/* set header font */ /* set header font */
SendMessageW(infoPtr->hwndHeader, WM_SETFONT, (WPARAM)infoPtr->hFont, (LPARAM)TRUE); SendMessageW(infoPtr->hwndHeader, WM_SETFONT, (WPARAM)infoPtr->hFont, (LPARAM)TRUE);
/* allocate memory for the selection ranges */
if (!(infoPtr->selectionRanges = ranges_create(10))) return -1;
infoPtr->hdpaColumns = DPA_Create(10); infoPtr->hdpaColumns = DPA_Create(10);
if (uView == LVS_ICON) if (uView == LVS_ICON)
...@@ -6919,9 +6911,6 @@ static LRESULT LISTVIEW_Create(HWND hwnd, LPCREATESTRUCTW lpcs) ...@@ -6919,9 +6911,6 @@ static LRESULT LISTVIEW_Create(HWND hwnd, LPCREATESTRUCTW lpcs)
infoPtr->hdpaPosX = DPA_Create(10); infoPtr->hdpaPosX = DPA_Create(10);
infoPtr->hdpaPosY = DPA_Create(10); infoPtr->hdpaPosY = DPA_Create(10);
/* allocate memory for the selection ranges */
infoPtr->selectionRanges = ranges_create(10);
/* initialize size of items */ /* initialize size of items */
infoPtr->nItemWidth = LISTVIEW_CalculateMaxWidth(infoPtr); infoPtr->nItemWidth = LISTVIEW_CalculateMaxWidth(infoPtr);
infoPtr->nItemHeight = LISTVIEW_CalculateMaxHeight(infoPtr); infoPtr->nItemHeight = LISTVIEW_CalculateMaxHeight(infoPtr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment