Home | History | Annotate | Download | only in src
      1 /*
      2  * list.c, list
      3  *
      4  * Copyright (c) 2009-2010 Wind River Systems, Inc.
      5  *
      6  * Licensed under the Apache License, Version 2.0 (the "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  * http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  */
     18 
     19 #include <stdlib.h>
     20 
     21 #include <list.h>
     22 
     23 void __list_init(struct list *entry)
     24 {
     25     if (entry) {
     26         entry->prev = NULL;
     27         entry->next = NULL;
     28         entry->data = NULL;
     29     }
     30 }
     31 
     32 struct list *__list_alloc(void)
     33 {
     34     struct list *new;
     35 
     36     new = malloc(sizeof(struct list));
     37     __list_init(new);
     38 
     39     return new;
     40 }
     41 
     42 struct list *list_alloc(void *data)
     43 {
     44     struct list *new;
     45 
     46     new = __list_alloc();
     47     if (new)
     48         new->data = data;
     49 
     50     return new;
     51 }
     52 
     53 void __list_free(struct list *entry)
     54 {
     55     free(entry);
     56 }
     57 
     58 void list_free_all(struct list *list)
     59 {
     60     struct list *ptr, *tmp;
     61 
     62     list_foreach_safe(list, ptr, tmp) {
     63         __list_free(ptr);
     64     }
     65 }
     66 
     67 struct list *__list_last(struct list *list)
     68 {
     69     if (list)
     70         while (list->next)
     71             list = list->next;
     72 
     73     return list;
     74 }
     75 
     76 struct list *__list_first(struct list *list)
     77 {
     78     if (list)
     79         while (list->prev)
     80             list = list->prev;
     81 
     82     return list;
     83 }
     84 
     85 struct list *__list_entry(struct list *list, int index)
     86 {
     87     struct list *entry;
     88     int i = 0;
     89 
     90     list_foreach(list, entry) {
     91         if (i == index)
     92             break;
     93         i++;
     94     }
     95 
     96     return entry;
     97 }
     98 
     99 int list_length(struct list *list)
    100 {
    101     int length = 0;
    102 
    103     while (list) {
    104         list = list->next;
    105         length++;
    106     }
    107 
    108     return length;
    109 }
    110 
    111 struct list *__list_add_before(struct list *entry, struct list *new)
    112 {
    113     struct list *prev;
    114 
    115     if (entry) {
    116         prev = entry->prev;
    117         if (prev)
    118             prev->next = new;
    119         new->prev = prev;
    120         new->next = entry;
    121         entry->prev = new;
    122     }
    123 
    124     return new;
    125 }
    126 
    127 struct list *__list_add_after(struct list *entry, struct list *new)
    128 {
    129     struct list *next;
    130 
    131     if (entry) {
    132         next = entry->next;
    133         if (next)
    134             next->prev = new;
    135         new->next = next;
    136         new->prev = entry;
    137         entry->next = new;
    138 
    139         return entry;
    140     }
    141 
    142     return new;
    143 }
    144 
    145 struct list *__list_add_head(struct list *list, struct list *new)
    146 {
    147     struct list *first;
    148 
    149     if (list) {
    150         first = __list_first(list);
    151         __list_add_before(first, new);
    152     }
    153 
    154     return new;
    155 }
    156 
    157 struct list *__list_add_tail(struct list *list, struct list *new)
    158 {
    159     struct list *last;
    160 
    161     if (list) {
    162         last = __list_last(list);
    163         __list_add_after(last, new);
    164 
    165         return list;
    166     }
    167     else
    168         return new;
    169 }
    170 
    171 struct list *list_add_head(struct list *list, void *data)
    172 {
    173     struct list *new;
    174 
    175     new = list_alloc(data);
    176     if (!new)
    177         return NULL;
    178 
    179     return __list_add_head(list, new);
    180 }
    181 
    182 struct list *list_add_tail(struct list *list, void *data)
    183 {
    184     struct list *new;
    185 
    186     new = list_alloc(data);
    187     if (!new)
    188         return NULL;
    189 
    190     return __list_add_tail(list, new);
    191 }
    192 
    193 struct list *__list_remove(struct list *list, struct list *entry)
    194 {
    195     struct list *prev, *next;
    196 
    197     if (entry) {
    198         prev = entry->prev;
    199         next = entry->next;
    200 
    201         if (prev)
    202             prev->next = next;
    203         else
    204             list = next;
    205         if (next)
    206             next->prev = prev;
    207 
    208         entry->prev = NULL;
    209         entry->next = NULL;
    210     }
    211 
    212     return list;
    213 }
    214 
    215 struct list *__list_delete(struct list *list,
    216                            struct list *entry)
    217 {
    218     list = __list_remove(list, entry);
    219     __list_free(entry);
    220 
    221     return list;
    222 }
    223 
    224 struct list *list_delete(struct list *list, void *data)
    225 {
    226     struct list *ptr, *tmp;
    227 
    228     list_foreach_safe(list, ptr, tmp) {
    229         if (ptr->data == data) {
    230             list = __list_delete(list, ptr);
    231             break;
    232         }
    233     }
    234 
    235     return list;
    236 }
    237 
    238 struct list *list_delete_all(struct list *list, void *data)
    239 {
    240     struct list *ptr, *tmp;
    241 
    242     list_foreach_safe(list, ptr, tmp) {
    243         if (ptr->data == data)
    244             list = __list_delete(list, ptr);
    245     }
    246 
    247     return list;
    248 }
    249 
    250 struct list *list_find(struct list *list, void *data)
    251 {
    252     struct list *ptr;
    253 
    254     list_foreach(list, ptr) {
    255         if (ptr->data == data)
    256             break;
    257     }
    258 
    259     return ptr;
    260 }
    261 
    262 struct list *list_find_reverse(struct list *list, void *data)
    263 {
    264     struct list *ptr;
    265 
    266     list_foreach_reverse(list, ptr) {
    267         if (ptr->data == data)
    268             break;
    269     }
    270 
    271     return ptr;
    272 }
    273