📄 dhcp-list.c
字号:
/* $Header: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-list.c,v 1.6 2003/04/28 22:21:52 actmodern Exp $ * * Copyright 2002 Thamer Alharbash <tmh@whitefang.com> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. The names of the authors may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#define MODULE_NAME "dhcp-list"#include "dhcp-local.h"#include "dhcp-libutil.h"/* create a new list. */list_t *list_create(void){ list_t *list; list = xcalloc(sizeof(list_t)); return list;}/* add an item to the list. */void list_add(list_t *list, void *data){ node_t *node; node = xcalloc(sizeof(node_t)); node->next = list->head; node->data = data; /* if there are no other datums the tail should be the node * too */ if(list->len == 0) list->tail = node; list->head = node; /* make the head the new node. */ list->len++; /* increment count. */ /* automatic rewind here. */ list_rewind(list); return;}/* add an item to the end of the list. */void list_add_to_end(list_t *list, void *data){ node_t *node; /* if it's the only item in the list just add it normally. */ if(list->len == 0) { list_add(list, data); return; } node = xcalloc(sizeof(node_t)); node->data = data; list->tail->next = node; list->tail = node; list->len++; /* automatic rewind here. */ list_rewind(list); return;}/* remove a list pointer by the datum. this does not free the * datum itself. */int list_remove_by_datum(list_t *list, void *data){ node_t *node, *node_prev; if(list->len == 0) /* nothing to remove. */ return 1; /* check if the datum is the head of the list. */ if(list->head->data == data) { /* just remove head. */ node = list->head; list->head = list->head->next; xfree(node); if(list->len == 1) /* then we should clear tail as well. */ list->tail = list->head; list->len--; /* automatic rewind here. */ list_rewind(list); return 0; } /* anything else means it's not the head and it's something further down. */ if(list->len == 1) return 1; /* can't be anything else then */ node_prev = list->head; for(node = list->head->next; node; node = node->next) { if(node->data == data) { node_prev->next = node->next; /* if we're pruning the last item then set previous to the tail. */ if(list->tail == node) list->tail = node_prev; xfree(node); list->len--; /* automatic rewind here. */ list_rewind(list); return 0; } node_prev = node; } /* we did not find it. */ return 1;}/* destroy a list. use purge_func to freeing the datum if it is set. */void list_destroy(list_t *list, void (*purge_func) (void *d)){ node_t *node, *node_next; if(list->len == 0) { /* nada, just destroy the list. */ xfree(list); return; } node = list->head; while(1) { node_next = node->next; if(purge_func) purge_func(node->data); xfree(node); node = node_next; if(node == NULL) break; } xfree(list); return;}/* concatenate second list to first list. second_list's data is * preserved but the list pointer itself is destroyed. */void list_join(list_t *first_list, list_t *second_list){ if(second_list->len == 0) { xfree(second_list); /* automatic rewind here. */ list_rewind(first_list); return; } if(first_list->len == 0) { first_list->len = second_list->len; first_list->head = second_list->head; first_list->tail = second_list->tail; xfree(second_list); /* automatic rewind here. */ list_rewind(first_list); return; } else { first_list->len += second_list->len; first_list->tail->next = second_list->head; first_list->tail = second_list->tail; xfree(second_list); /* automatic rewind here. */ list_rewind(first_list); return; }}/* we use a fairly dumb sorting algorithm. we recreate a list * and add the datums into it. once done just free up the old list * without freeing the datums and return the new sorted list. */list_t *list_sort(list_t *list, int (*compare) (void *, void *)){ node_t *node_walk, *node_highest; list_t *new_list; if(list->len <= 1) /* one or less means we cannot sort. */ return list; new_list = list_create(); while(1) { if(list->len == 1) { list_add_to_end(new_list, list->head->data); list_remove_by_datum(list, list->head->data); break; } node_highest = list->head; for(node_walk = list->head->next; node_walk; node_walk = node_walk->next) { if(compare(node_highest->data, node_walk->data) == 1) { node_highest = node_walk; } } list_add_to_end(new_list, node_highest->data); list_remove_by_datum(list, node_highest->data); } list_destroy(list, NULL); return new_list;}void *list_get_by_index(list_t *list, int index){ int i; node_t *node; if(list->len == 0) return NULL; if((list->len -1) < index) return NULL; i = 0; for(node = list->head; node && i < index; node = node->next) { i++; } if(node == NULL) return NULL; return node->data;}/* useful routines for pairs. */void *list_first(list_t *list){ return list_get_by_index(list, 0);}void *list_second(list_t *list){ return list_get_by_index(list, 1);}/* useful for walking a list. */void list_rewind(list_t *list){ list->seek = list->head; return;}void *list_next(list_t *list){ void *data; if(list->seek == NULL) return NULL; data = list->seek->data; list->seek = list->seek->next; return data;}int list_get_len(list_t *list){ return list->len;}list_t *list_copy(list_t *list, size_t data_size){ uint8_t *src_data; uint8_t *new_data; list_t *new_list; new_list = list_create(); list_rewind(list); while((src_data = list_next(list)) != NULL) { new_data = xmalloc(data_size); memcpy(new_data, src_data, data_size); list_add(new_list, new_data); } return new_list;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -