int Chtbl_Remove(CHTbl *htbl, void **data) { ListElmt *element = NULL; ListElmt *prev = NULL; //暂存前一项元素的内容,便于释放list ListElmt *start_element = NULL; int bucket = 0; bucket = htbl->h(*data) % htbl->buckets; start_element = List_Head(&htbl->table[bucket]); /* 在桶里查找数据 */ for (element = start_element; element != NULL; element = List_Next(element)) { if (htbl->match(*data, List_Data(element))) { if (OK == List_Rem_Next(&htbl->table[bucket], prev, data)) { htbl->size--; return OK; } else { return ERR; } } prev = element; } //未查找到数据 return ERR; }
static var List_At(struct List* l, int64_t i) { i = i < 0 ? l->nitems+i : i; #if CELLO_BOUND_CHECK == 1 if (i < 0 or i >= (int64_t)l->nitems) { return throw(IndexOutOfBoundsError, "Index '%i' out of bounds for List of size %i.", $(Int, i), $(Int, l->nitems)); } #endif var item; if (i <= (int64_t)(l->nitems / 2)) { item = l->head; while (i) { item = *List_Next(l, item); i--; } } else { i = l->nitems-i-1; item = l->tail; while (i) { item = *List_Prev(l, item); i--; } } return item; }
//------------------------------------------------------------------- void FunctionTable_DumpInfo(FILE* fp) { List_Reset(g_FunctionList); while(!List_EOF(g_FunctionList)) { Function_Dump(List_Current(g_FunctionList), fp); List_Next(g_FunctionList); } }
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; } }
static void List_Clear(var self) { struct List* l = self; var item = l->head; while (item) { var next = *List_Next(l, item); destruct(item); List_Free(l, item); item = next; } l->tail = NULL; l->head = NULL; l->nitems = 0; }
/* * 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); } } }
//------------------------------------------------------------------- TFunctionId FunctionTable_GetId(const char* FunctionName) { ASSERT(g_Initialized != 0); ASSERT(FunctionName != NULL); List_Reset(g_FunctionList); while(!List_EOF(g_FunctionList) && 0 != strcmp(((TFunction*)List_Current(g_FunctionList))->Name, FunctionName) ) List_Next(g_FunctionList); if(List_EOF(g_FunctionList)) { // No existe funcion! DEBUG_msg_str("No existe una funcion con el nombre: ", FunctionName); return NULL; } return (TFunctionId)List_Current(g_FunctionList); }
int Chtbl_Lookup(CHTbl *htbl, void **data) { ListElmt *element = NULL; ListElmt *start_element = NULL; int bucket = 0; //计算所在桶的位置 bucket = htbl->h(*data) % htbl->buckets; start_element = List_Head(&htbl->table[bucket]); /* 在桶里查找数据 */ for (element = start_element; element != NULL; element = List_Next(element)) { if (htbl->match(*data, List_Data(element))) { *data = List_Data(element); return OK; } } //未查找到数据 return ERR; }
/* * 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); } } }
HashItem * HashTableSlot_Next(HashTableSlot *self, HashItem *in_item) { return (HashItem *)List_Next(&self->mBase, &in_item->mBase); }