1 | /* |
---|
2 | * JFFS2 -- Journalling Flash File System, Version 2. |
---|
3 | * |
---|
4 | * |
---|
5 | * Created by Jonathan Larmour <jlarmour@redhat.com> |
---|
6 | * |
---|
7 | *=========================================================================== |
---|
8 | * ####ECOSGPLCOPYRIGHTBEGIN#### |
---|
9 | * ------------------------------------------- |
---|
10 | * This file is part of eCos, the Embedded Configurable Operating System. |
---|
11 | * Copyright (C) 2002, 2003 Free Software Foundation, Inc. |
---|
12 | * |
---|
13 | * eCos is free software; you can redistribute it and/or modify it under |
---|
14 | * the terms of the GNU General Public License as published by the Free |
---|
15 | * Software Foundation; either version 2 or (at your option) any later |
---|
16 | * version. |
---|
17 | * |
---|
18 | * eCos is distributed in the hope that it will be useful, but WITHOUT |
---|
19 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
20 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
---|
21 | * for more details. |
---|
22 | * |
---|
23 | * You should have received a copy of the GNU General Public License |
---|
24 | * along with eCos; if not, write to the Free Software Foundation, Inc., |
---|
25 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
---|
26 | * |
---|
27 | * As a special exception, if other files instantiate templates or use |
---|
28 | * macros or inline functions from this file, or you compile this file |
---|
29 | * and link it with other works to produce a work based on this file, |
---|
30 | * this file does not by itself cause the resulting work to be covered by |
---|
31 | * the GNU General Public License. However the source code for this file |
---|
32 | * must still be made available in accordance with section (3) of the GNU |
---|
33 | * General Public License v2. |
---|
34 | * |
---|
35 | * This exception does not invalidate any other reasons why a work based |
---|
36 | * on this file might be covered by the GNU General Public License. |
---|
37 | * ------------------------------------------- |
---|
38 | * ####ECOSGPLCOPYRIGHTEND#### |
---|
39 | *=========================================================================== |
---|
40 | * |
---|
41 | */ |
---|
42 | |
---|
43 | #ifndef CYGONCE_FS_JFFS2_LIST_H |
---|
44 | #define CYGONCE_FS_JFFS2_LIST_H |
---|
45 | |
---|
46 | |
---|
47 | /* -----------------------------------------------------------------------*/ |
---|
48 | |
---|
49 | /* Doubly linked list implementation to replace the GPL'd one used in |
---|
50 | the Linux kernel. */ |
---|
51 | |
---|
52 | #include <stddef.h> |
---|
53 | #include <cyg/infra/cyg_type.h> |
---|
54 | |
---|
55 | /* TYPES */ |
---|
56 | |
---|
57 | struct list_head { |
---|
58 | struct list_head *next; |
---|
59 | struct list_head *prev; |
---|
60 | }; |
---|
61 | |
---|
62 | /* MACROS */ |
---|
63 | |
---|
64 | #define LIST_HEAD_INIT(name) { &(name), &(name) } |
---|
65 | |
---|
66 | #define LIST_HEAD(name) \ |
---|
67 | struct list_head name = LIST_HEAD_INIT(name) |
---|
68 | |
---|
69 | #define INIT_LIST_HEAD( _list_ ) \ |
---|
70 | CYG_MACRO_START \ |
---|
71 | (_list_)->next = (_list_)->prev = (_list_); \ |
---|
72 | CYG_MACRO_END |
---|
73 | |
---|
74 | /* FUNCTIONS */ |
---|
75 | |
---|
76 | /* Insert an entry _after_ the specified entry */ |
---|
77 | static __inline__ void |
---|
78 | list_add( struct list_head *newent, struct list_head *afterthisent ) |
---|
79 | { |
---|
80 | struct list_head *next = afterthisent->next; |
---|
81 | newent->next = next; |
---|
82 | newent->prev = afterthisent; |
---|
83 | afterthisent->next = newent; |
---|
84 | next->prev = newent; |
---|
85 | } /* list_add() */ |
---|
86 | |
---|
87 | /* Insert an entry _before_ the specified entry */ |
---|
88 | static __inline__ void |
---|
89 | list_add_tail( struct list_head *newent, struct list_head *beforethisent ) |
---|
90 | { |
---|
91 | struct list_head *prev = beforethisent->prev; |
---|
92 | newent->prev = prev; |
---|
93 | newent->next = beforethisent; |
---|
94 | beforethisent->prev = newent; |
---|
95 | prev->next = newent; |
---|
96 | } /* list_add_tail() */ |
---|
97 | |
---|
98 | /* Delete the specified entry */ |
---|
99 | static __inline__ void |
---|
100 | list_del( struct list_head *ent ) |
---|
101 | { |
---|
102 | ent->prev->next = ent->next; |
---|
103 | ent->next->prev = ent->prev; |
---|
104 | } /* list_del() */ |
---|
105 | |
---|
106 | static __inline__ void |
---|
107 | list_move( struct list_head *list, struct list_head *head ) |
---|
108 | { |
---|
109 | list_del( list ); |
---|
110 | list_add( list, head ); |
---|
111 | } |
---|
112 | |
---|
113 | static __inline__ void |
---|
114 | list_move_tail( struct list_head *list, struct list_head *head ) |
---|
115 | { |
---|
116 | list_del( list ); |
---|
117 | list_add_tail( list, head ); |
---|
118 | } |
---|
119 | |
---|
120 | /* Is this list empty? */ |
---|
121 | static __inline__ int |
---|
122 | list_empty( struct list_head *list ) |
---|
123 | { |
---|
124 | return ( list->next == list ); |
---|
125 | } /* list_empty() */ |
---|
126 | |
---|
127 | /* list_entry - Assuming you have a struct of type _type_ that contains a |
---|
128 | list which has the name _member_ in that struct type, then given the |
---|
129 | address of that list in the struct, _list_, this returns the address |
---|
130 | of the container structure */ |
---|
131 | |
---|
132 | #define list_entry( _list_, _type_, _member_ ) \ |
---|
133 | ((_type_ *)((char *)(_list_)-(char *)(offsetof(_type_,_member_)))) |
---|
134 | |
---|
135 | /* list_for_each - using _ent_, iterate through list _list_ */ |
---|
136 | |
---|
137 | #define list_for_each( _ent_, _list_ ) \ |
---|
138 | for ( (_ent_) = (_list_)->next; \ |
---|
139 | (_ent_) != (_list_); \ |
---|
140 | (_ent_) = (_ent_)->next ) |
---|
141 | |
---|
142 | /* |
---|
143 | * list_for_each_entry - this function can be use to iterate over all |
---|
144 | * items in a list* _list_ with it's head at _head_ and link _item_ |
---|
145 | */ |
---|
146 | #define list_for_each_entry(_list_, _head_, _item_) \ |
---|
147 | for ((_list_) = list_entry((_head_)->next, typeof(*_list_), _item_); \ |
---|
148 | &((_list_)->_item_) != (_head_); \ |
---|
149 | (_list_) = list_entry((_list_)->_item_.next, typeof(*_list_), _item_)) |
---|
150 | |
---|
151 | /* -----------------------------------------------------------------------*/ |
---|
152 | #endif /* #ifndef CYGONCE_FS_JFFS2_LIST_H */ |
---|
153 | /* EOF list.h */ |
---|