static void removeItem(int color, List_Links *list) { Item *i; assert(!List_IsEmpty(list)); assert(((Item *)List_First(list))->color == color); i = (Item *)List_First(list); List_Remove((List_Links *)i); assert(i->color == color); free(i); return; }
int main(void) { INIT(); long int i; Object list = List_Create(); Object iterator; for(i = 0; i < NODES; i++) { List_PushFront(list, INT_AS_OBJECT(i)); }; List_Sort(list); ; for(iterator = List_First(list), i = 0; !ListIterator_ThisEnd(iterator); ListIterator_Next(iterator), i++) { if(OBJECT_AS_INT(ListIterator_ThisData(iterator)) != i) { DEBUG("Got %li, but %li expected.\n", OBJECT_AS_INT(ListIterator_ThisData(iterator)), i); return 1; }; }; Object_Release(list); return 0; };
struct MinNode *List_Find(APTR list, ULONG num) { struct MinNode *node = List_First(list); while(num--) { if(!(node = Node_Next(node))) break; } return node; }
ULONG List_Length(APTR list) { struct MinNode *node = List_First(list); ULONG len=0; while(node) { len++; node = Node_Next(node); } return len; }
void List_Finalize(List *self) { ListItem *item, *next; item = List_First(self); while (item != NULL) { next = List_Next(self, item); List_Unchain(self, item); List_DeleteItem(self, item); item = next; } }
/* * force a reset of each line in the list. line_reset discards any * links between lines, and any hashcode information. This would be used if * the compare options or hashcode options have changed. */ void file_reset(FILEDATA fd) { LINE line; if (fd == NULL) { return; } if (fd->lines != NULL) { for( line=(LINE)List_First(fd->lines); line!=NULL; line =(LINE) List_Next((LPVOID)line)) { line_reset(line); } } }
Object File_WriteNakedString(Object _self, Object _list) { File entity = _self->entity; char buffer[16]; long code; long length; Object iterator = List_First(_list); while(ListIterator_ThisEnd(iterator) != _true) { code = Number_GetLong(Char_GetCode(ListIterator_ThisData(iterator))); length = UTF8GetLengthOfCode(code); UTF8PutChar(buffer, code, length); OSfileWrite(entity->_descriptor, buffer, length); ListIterator_Next(iterator); } return _self; }
int PC_Get(PC *pc, int color) { Lock_Acquire(&pc->lock); assert(color <= pc->maxColor); while(List_IsEmpty(&(pc->list)) || (((Item *)List_First(&(pc->list)))->color != color)){ pc->waitingC++; Cond_Wait(&pc->stuffAvail, &pc->lock); pc->waitingC--; } removeItem(color, &(pc->list)); pc->used--; Cond_Signal(&pc->spaceAvail, &pc->lock); /* * We just took top item off -- another getter may be * able to proceed */ Cond_Broadcast(&pc->stuffAvail, &pc->lock); Lock_Release(&pc->lock); return color; }
int main(void) { INIT(); int i, j; Object list = List_Create(); for(j = 0; j < TIMES; j++) { Object front, back; for(i = 0; i < NODES; i++) { if(i & 1) { List_PushBack(list, INT_AS_OBJECT(i)); } else { List_PushFront(list, INT_AS_OBJECT(i)); }; }; front = List_First(list); back = List_Last(list); while(!ListIterator_ThisEnd(front)) { ListIterator_Next(front); ListIterator_Prev(back); }; if(!ListIterator_ThisBegin(back)) { return 1; }; List_Clean(list); }; Object_Release(list); return 0; };
/* * discard the list of lines associated with a file. this will cause * the file to be re-read next time file_getlinelist is called. */ void file_discardlines(FILEDATA fd) { LINE line; if (fd == NULL) { return; } if (fd->lines != NULL) { /* clear each line to free any memory associated * with them, then discard the entire list */ for( line=(LINE)List_First(fd->lines); line!=NULL; line = (LINE)List_Next((LPVOID)line)) { line_delete(line); } List_Destroy(&fd->lines); } /* this is probably done in List_Destroy, but better do it anyway*/ fd->lines = NULL; }
/* the compare options have changed - re-do the compare completely * and make the new mapping. Retain current position in the file. */ void view_changediffoptions(VIEW view) { int state, number; long row; BOOL bRight = FALSE; LIST li; COMPITEM ci; number = 0; if (view == NULL) { return; } /* * get current row before entering critsec. */ row = (long) SendMessage(view->hwnd, TM_TOPROW, FALSE, 0); ViewEnter(); /* find the current line number so we can go back to it * (only if we are in expanded mode */ if (view->bExpand) { state = section_getstate(view->pLines[row].section); if ((state == STATE_MOVEDRIGHT) || (state == STATE_SIMILARRIGHT) || (state == STATE_RIGHTONLY)) { bRight = TRUE; number = view->pLines[row].nr_right; } else { bRight = FALSE; number = view->pLines[row].nr_left; } } /* to force a recompare using the new options, we must * tell each compitem to discard its current compare result. * we need to traverse the list of compitems calling this * for each compare. */ li = complist_getitems(view->cl); for (ci = (COMPITEM) List_First(li); ci != NULL; ci = (COMPITEM) List_Next(ci)) { compitem_discardsections(ci); } if (!view->bExpand) { ViewLeave(); // we are in outline mode. Refreshing the outline view // will pick up any tag and tag width changes view_outline(view); // now scroll to the previous position if still there if (row < view->rows) { SendMessage(view->hwnd, TM_TOPROW, TRUE, row); } return; } view_expand_item(view, view->ciSelect); /* find the nearest row in the new view */ ViewEnter(); row = view_findrow(view, number, bRight); ViewLeave(); /* scroll this row to top of window */ if (row >= 0) { SendMessage(view->hwnd, TM_TOPROW, TRUE, row); } }
/* expand a view - given the handle to the compitem to expand. * * called from view_expand, and also to re-do an expanded view * after options change in view_changediffoptions and _changeviewoptions * * we get the composite section list from the compitem, * and pick out all the sections that are includable (according * to the global option expand_mode: we include all sections, or * just those in one side left or right). Once we know the count of rows, * allocate the mapping array: in each element of the array we keep * a handle to the section for that row (to get the state and hence the * tag text), and a handle to the line within that section (for the line text). * * We no longer insist on only expanding text files that differ - if the * compitem can give us a composite section list, we will map it. * * We need to be able to give a line number for a line, in either of * the original files according to which option is in force. Each section * can give us its base line number (number of first line in section) in * each of the two files or 0 if not present, and we track these here. * * MUST BE INSIDE CSView BEFORE CALLING HERE. */ BOOL view_expand_item( VIEW view, COMPITEM ci ) { LIST li; SECTION sh; LINE line1, line2; int i, base_left, base_right, state; // We could be on a second thread trying to expand while it's // already going on. That ain't clever! if (view->bExpandGuard) { Trace_Error(NULL, "Expansion in progress. Please wait.", FALSE); ViewLeave(); return FALSE; } // Ensure that the world knows that we are expanding // before we leave the critical section. // This is the only way into getcomposite. view->bExpandGuard = TRUE; // the compitem_getcomposite could take a long time // if the file is large and remote. We need to // release the critsec during this operation. ViewLeave(); /* get the composite section list */ li = compitem_getcomposite(ci); if (li == NULL) { view->bExpanding = FALSE; view->bExpandGuard = FALSE; return FALSE; } ViewEnter(); /* remember the compitem we are expanding */ view->ciSelect = ci; /* switch modes and free the current mapping * * NOTE: must do this AFTER the compitem_getcomposite, * since that can fail: if it fails it could put up a * message box, and that could cause a queued paint message * to be processed, which would cause us to use these mappings * and gpfault if they had been cleared first. */ view->bExpand = TRUE; view->bExpanding = FALSE; view->bExpandGuard = FALSE; view_freemappings(view); /* loop through totalling the lines in sections * that we should include */ view->rows = 0; for ( sh = (SECTION) List_First(li); sh != NULL; sh = (SECTION) List_Next(sh)) { state = section_getstate(sh); if (expand_mode == IDM_RONLY) { if ((state == STATE_LEFTONLY) || (state == STATE_SIMILARLEFT) || (state == STATE_MOVEDLEFT)) { continue; } } else if (expand_mode == IDM_LONLY) { if ((state == STATE_RIGHTONLY) || (state == STATE_SIMILARRIGHT) || (state == STATE_MOVEDRIGHT)) { continue; } } /* include all lines in this section if the section meets the include criteria */ if ( ((state == STATE_SAME) && (expand_include & INCLUDE_SAME)) || ((state == STATE_LEFTONLY) && (expand_include & INCLUDE_LEFTONLY)) || ((state == STATE_RIGHTONLY) && (expand_include & INCLUDE_RIGHTONLY)) || ((state == STATE_MOVEDLEFT) && (expand_include & INCLUDE_MOVEDLEFT)) || ((state == STATE_MOVEDRIGHT) && (expand_include & INCLUDE_MOVEDRIGHT)) || ((state == STATE_SIMILARLEFT) && (expand_include & INCLUDE_SIMILARLEFT)) || ((state == STATE_SIMILARRIGHT) && (expand_include & INCLUDE_SIMILARRIGHT))) { view->rows += section_getlinecount(sh); } } /* allocate the memory for the mapping array */ { /* DO NOT chain in any storage with garbage pointers in it */ PVIEWLINE temp; temp = (PVIEWLINE) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, view->rows * sizeof(VIEWLINE)); if (temp == NULL) { return FALSE; } view->pLines = temp; } /* loop through the sections again filling in the mapping array */ i = 0; view->maxtag = 5; view->maxrest = 0; for (sh = (SECTION) List_First(li); sh != NULL; sh = (SECTION) List_Next(sh)) { state = section_getstate(sh); if (expand_mode == IDM_RONLY) { if ((state == STATE_LEFTONLY) || (state == STATE_SIMILARLEFT) || (state == STATE_MOVEDLEFT)) { continue; } } else if (expand_mode == IDM_LONLY) { if ((state == STATE_RIGHTONLY) || (state == STATE_SIMILARRIGHT) || (state == STATE_MOVEDRIGHT)) { continue; } } /* include all lines in this section if the section meets the include criteria */ if ( ((state == STATE_SAME) && (expand_include & INCLUDE_SAME)) || ((state == STATE_LEFTONLY) && (expand_include & INCLUDE_LEFTONLY)) || ((state == STATE_RIGHTONLY) && (expand_include & INCLUDE_RIGHTONLY)) || ((state == STATE_MOVEDLEFT) && (expand_include & INCLUDE_MOVEDLEFT)) || ((state == STATE_MOVEDRIGHT) && (expand_include & INCLUDE_MOVEDRIGHT)) || ((state == STATE_SIMILARLEFT) && (expand_include & INCLUDE_SIMILARLEFT)) || ((state == STATE_SIMILARRIGHT) && (expand_include & INCLUDE_SIMILARRIGHT))) { /* find the base line number in each file */ base_left = section_getleftbasenr(sh); base_right = section_getrightbasenr(sh); /* add each line in section to the view. section_getfirst() * returns us to a handle that is in a list. We can * call List_Next and will eventually get to the * line returned by section_getlast(). Sections always have * at least one line */ line1 = section_getfirstline(sh); line2 = section_getlastline(sh); for (; line1 != NULL; line1 = (LINE) List_Next(line1)) { view->pLines[i].line = line1; view->pLines[i].section = sh; /* calculate the line number for this line by * incrementing the base nr for this section. * Note SIMILAR_RIGHT (or LEFT) lines DO have * left (or right) numbers, but they are dummies. */ view->pLines[i].nr_left = base_left; if (state!=STATE_SIMILARRIGHT && base_left != 0) { base_left++; } view->pLines[i].nr_right = base_right; if (state!=STATE_SIMILARLEFT && base_right != 0) { base_right++; } /* increment index into view */ i++; /* check the column widths */ view->maxrest = max(view->maxrest, (line_gettabbedlength(line1, g_tabwidth))); /* end of section ? */ if (line1 == line2) { break; } } } } /* We must NOT hold a critical section here as SendMessage may hang */ ViewLeave(); /*inform table window of revised mapping */ SendMessage(view->hwnd, TM_NEWLAYOUT, 0, (LPARAM) view); return(TRUE); }
/* build a view outline to map one row to a COMPITEM handle by traversing * the list of COMPITEMs obtained from our complist. * optionally tell the table class to redraw (if bRedraw), and if so, * scroll the new table to select the row that represents the * file we were expanding, if possible * * *important*: if you are holding the view critsec when you call this, you * must pass bRedraw as FALSE or you could deadlock * * if a COMPITEM ci is passed in, then return in *prow the row number that * corresponds to this item in the new view, or if not visible, the first * visible row after it (to retain current scroll position) */ void view_outline_opt( VIEW view, BOOL bRedraw, COMPITEM ciFind, int * prow ) { int prev_row = -1; /* the row nr of the previously-expanded row*/ int i; /* nr of includable items */ LIST li; COMPITEM ci; int state; TableSelection select; /* * check that view_setcomplist has already been called. if not, * nothing to do */ if (view->cl == NULL) { return; } ViewEnter(); /* clear the mode flag and free up memory associated with expand mode */ view->bExpand = FALSE; view_freemappings(view); /* traverse the list of compitems counting up the number of * includable items */ li = complist_getitems(view->cl); ci = (COMPITEM) List_First(li); for (i = 0; ci != NULL; ci = (COMPITEM) List_Next(ci)) { if ((ciFind != NULL) && (prow != NULL)) { if (ci == ciFind) { // now that we have found the requested item, // the next visible row is the one we want, // whether it is ci or a later one *prow = i; } } state = compitem_getstate(ci); if (((outline_include & INCLUDE_SAME) && (state == STATE_SAME)) || ((outline_include & INCLUDE_DIFFER) && (state == STATE_DIFFER)) || ((outline_include & INCLUDE_LEFTONLY) && (state == STATE_FILELEFTONLY)) || ((outline_include & INCLUDE_RIGHTONLY) && (state == STATE_FILERIGHTONLY))) { if (!compitem_getmark(ci) || !hide_markedfiles) { i++; } } } /* allocate an array big enough for all of these */ { /* DO NOT link in any storage with garbage pointers in it */ COMPITEM * temp; temp = (COMPITEM *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, i * sizeof(COMPITEM)); if (temp == NULL) { return; } view->pItems = temp; } view->rows = i; /* keep track of the column widths */ view->maxtag = 0; view->maxrest = 0; /* loop through again filling the array, and at the same time looking * out for the handle of the previously expanded item */ ci = (COMPITEM) List_First(li); for (i = 0; ci != NULL; ci = (COMPITEM) List_Next(ci)) { state = compitem_getstate(ci); if (((outline_include & INCLUDE_SAME) && (state == STATE_SAME)) || ((outline_include & INCLUDE_DIFFER) && (state == STATE_DIFFER)) || ((outline_include & INCLUDE_LEFTONLY) && (state == STATE_FILELEFTONLY)) || ((outline_include & INCLUDE_RIGHTONLY) && (state == STATE_FILERIGHTONLY))) { if (!compitem_getmark(ci) || !hide_markedfiles) { view->pItems[i] = ci; if (ci == view->ciSelect) { prev_row = i; } /* check the column widths in characters */ view->maxtag = max(view->maxtag, lstrlen(compitem_gettext_tag(ci))); view->maxrest = max(view->maxrest, lstrlen(compitem_gettext_result(ci))); i++; } } } ViewLeave(); /* inform table of new layout of table - force refresh */ if (bRedraw) { SendMessage(view->hwnd, TM_NEWLAYOUT, 0, (LPARAM) view); /* scroll to and highlight the row that represents the file * we were previously expanding */ if (prev_row != -1) { select.startrow = prev_row; select.startcell = 0; select.nrows = 1; select.ncells = 1; SendMessage(view->hwnd, TM_SELECT, 0, (LPARAM) &select); } } }
int main(void) { INIT(); long int i; int l = 10, r = 5; Object list = List_Create(); Object list2 = List_Create(); Object temp_list; Object front, back; // list2 = (0 1 2 3 4 5 6 ... 148 149) for(i = 0; i < l + r; i++) { List_PushBack(list2, INT_AS_OBJECT(i)); }; // list = (99998 99996 ... 8 6 4 2 0 1 3 5 7 9 ... 99997 99999 ) for(i = 0; i < NODES; i++) { if(i & 1) { List_PushBack(list, INT_AS_OBJECT(i)); } else { List_PushFront(list, INT_AS_OBJECT(i)); }; }; for(front = List_First(list), i = 0; i < NODES / 2; ListIterator_Next(front), i++) { List_AddAfterPosition(list2, INT_AS_OBJECT(l - 1 + i), ListIterator_ThisData(front)); }; for(back = List_Last(list), i = 0; i < NODES / 2; ListIterator_Prev(back), i++) { List_AddAfterPosition(list2, INT_AS_OBJECT(l + NODES / 2 - 1), ListIterator_ThisData(back)); }; front = List_IteratorFromPosition(list2, INT_AS_OBJECT(l)); TEST("Checking for correctness of IteratorFromPosition after AddList{Before|After}", OBJECT_AS_INT(ListIterator_ThisData(front)) == (NODES & (~1)) - ((!(NODES & 1)) * 2)); back = List_IteratorFromPosition(list2, INT_AS_OBJECT(l + NODES - 1)); TEST("Checking for correctness of IteratorFromPosition after AddList{Before|After}", OBJECT_AS_INT(ListIterator_ThisData(back)) == (NODES & (~1)) - 1 + ((NODES & 1) * 2)); temp_list = List_SublistBetweenIterators(list2, front, back); front = List_First(temp_list); back = List_Last(temp_list); for(i = 1; i < NODES / 2; i++) { if(OBJECT_AS_INT(ListIterator_ThisData(front)) != OBJECT_AS_INT(ListIterator_ThisData(back)) + 1) { DEBUG("Got %li and %li.\n", OBJECT_AS_INT(ListIterator_ThisData(front)), OBJECT_AS_INT(ListIterator_ThisData(back))); return 1; }; ListIterator_Next(front); ListIterator_Prev(back); }; Object_Release(list); Object_Release(list2); Object_Release(temp_list); return 0; };
HashItem * HashTableSlot_First(HashTableSlot *self) { return (HashItem *)List_First(&self->mBase); }