Hosted by the courtesy of  
http://www.free.fr 
The stars ASAP english francais spanish arab
Durée du voyage intersidéral francais
Résolutions de l'ONU en HTML francais
Bussard Ramjet english francais
DWARF : dwarf2xml english
ELF : libelf examples english
Code presentation : ctoohtml english

To rings Doc++

File Index

All Tags

Tags by File

Tags referrers

file: ring.h


  1 /*
  2 * Copyright (C) 2008-2009 by Emmanuel Azencot under the GNU LGPL
  3 * license version 2.0 or 2.1.  You should have received a copy of the
  4 * LGPL license along with this library if you did not you can find it
  5 * at http://www.gnu.org/.
  6 */

  7 /*
  8 * Azencot : Wed Nov 12 21:45:57 CET 2008
  9 *  Creation
 10 * Azencot : Tue Nov 18 21:31:30 CET 2008
 11 *  Add doc++ comments
 12 * Azencot : Sat Dec 13 00:20:02 CET 2008
 13 *  f_ring_off_xxx -> f_ring_xxx
 14 */

 15 #ifndef _RING_H_ /* [ */
 16 #define /*X*/ _RING_H_
 17
 18 #include <stddef.h> /* offsetof */
 19 #include <stdbool.h>
 20
 21 /**@name Structures
 22 * @doc
 23 *  The easiest way to use rings is to include a ring structure in your C object
 24 * structure :
 25 * <pre>
 26     struct s_your_object {
 27        type member;
 28        ...
 29        struct s_ring sibling;
 30        type member;
 31        ....
 32     };</pre>
 33 *  The set of macros use the ring structure member name to find the offset of
 34 * the ring structure in yours.
 35 *  These macros try to keep type informations as far as possible for the compiler
 36 * to be able to check them.
 37 */

 38 //@{
 39 /** @memo The ring structure
 40 * @doc
 41 *  You must include in your own structure at the same offset, for all nodes
 42 * of the same ring.
 43 * It is recommended to include the ring structure directly in the node one.
 44 * The macros need a member reference to find the ring part.
 45 */

 46 struct /*X*/ s_ring { struct /*X*/ s_ring *next; };
 47 /** @memo double linked object
 48 * @doc
 49 *  These kind of rings provides 2 extar methodes : previous and move..
 50 */

 51 struct /*X*/ s_dring { struct /*X*/ s_dring *next; struct /*X*/ s_dring *prev; };
 52 /** @memo Include this structure for named object
 53 * @doc
 54 *  The node name is a null terminated string pointer. Caller is responsible
 55 * of memory management for the name.
 56 *  Name must be less than 1000 characters.
 57 */

 58 struct /*X*/ s_nring { struct /*X*/ s_nring *next; const char *name; };
 59 /** @memo Double linked named object
 60 * @doc
 61 *  The node name is a null terminated string pointer. Caller is responsible
 62 * of memory management for the name.
 63 *  Name must be less than 1000 characters.
 64 */

 65 struct /*X*/ s_ndring { struct /*X*/ s_ndring *next; struct /*X*/ s_ndring *prev; char *name; };
 66 //@}
 67 /**@name Selftest (macro)
 68 * @memo The ring integrity routine.
 69 * @doc
 70 *  These macros call the same routine that is it used when check_opt is set.
 71 * Feel free to call it in case you have disabled this check.
 72 * @param p_ring (IN) A holding pointer to a node's ring
 73 * @param field (IN) Field member name of ring structure
 74 * @return 0 is failled
 75 * @exception EMLINK null pointer found in ring link.
 76 */

 77 //@{
 78 /// ring
 79 #define /*X*/ m_ring_selftest(p_ring, field) ( \
 80   (typeof(p_ring))f_ring_selftest(&((p_ring)->field), offsetof(typeof(*(p_ring)), field) ) )

 81 /// nring
 82 #define /*X*/ m_nring_selftest(p_ring, field) ( \
 83   (typeof(p_ring))f_nring_selftest(&((p_ring)->field), offsetof(typeof(*(p_ring)), field) ) )

 84 /// dring
 85 #define /*X*/ m_dring_selftest(p_ring, field) ( \
 86   (typeof(p_ring))f_dring_selftest(&((p_ring)->field), offsetof(typeof(*(p_ring)), field) ) )

 87 /// ndring
 88 #define /*X*/ m_ndring_selftest(p_ring, field) ( \
 89   (typeof(p_ring))f_ndring_selftest(&((p_ring)->field), offsetof(typeof(*(p_ring)), field) ) )

 90 //@}
 91 /**@name Test node is in a ring (macro)
 92 * @memo Is this node in the this ring ?.
 93 * @doc
 94 *   Lost your ring ? Just try all you have with this method.
 95 * + missing macro.
 96 * @param is (IN) this node is
 97 * @param in (IN) this ring
 98 * @return 0 if not
 99 * @exception EFAULT is is nil.
100 * @exception EMLINK null pointer found in ring link.
101 */

102 //@{
103 /// ring
104 #define /*X*/ m_ring_is_in(is, in, field)  (f_ring_is_in(&((is)->field), &((in)->field), offsetof(typeof(*(in)), field) ) )
105 /// nring
106 #define /*X*/ m_nring_is_in(is, in, field) (f_nring_is_in(&((is)->field), &((in)->field), offsetof(typeof(*(in)), field) ) )
107 /// dring
108 #define /*X*/ m_dring_is_in(is, in, field) (f_dring_is_in(&((is)->field), &((in)->field), offsetof(typeof(*(in)), field) ) )
109 /// ndring
110 #define /*X*/ m_ndring_is_in(is, in, field) (f_ndring_is_in(&((is)->field), &((in)->field), offsetof(typeof(*(in)), field) ) )
111 //@}
112 /**@name Link (macro)
113 * @memo Hold a new node in the ring.
114 * @doc
115 *   if ring reference is nul, the operation succed. To avoid side effect on empty rings,
116 * always set the ring holding pointer with the result of the call :
117 * <pre>ring_ptr = m_ring_link(ring_ptr, field, node);</pre>
118 * @param p_ring (IN) a pointer to your structure node
119 * @param field (IN) the ring structure field name in the node structure.
120 * @param node (IN) the node
121 * @return node in the now in ring.
122 * @exception ENOTNAM, Name is nil (nring, ndring).
123 * @exception ENAMETOOLONG, Name is too long (nring, ndring).
124 * @exception EEXIST, node is already in ring.
125 * @exception EFAULT node is nil.
126 * @exception EMLINK null pointer found in ring link.
127 */

128 //@{
129 /// ring
130 #define /*X*/ m_ring_link(p_ring, field, node) ( (typeof(p_ring))f_ring_link(&((p_ring)->field), &((node)->field), offsetof(typeof(*(p_ring)), field) ) )
131 /// nring
132 #define /*X*/ m_nring_link(p_ring, field, node) ( (typeof(p_ring))f_nring_link(&((p_ring)->field), &((node)->field), offsetof(typeof(*(p_ring)), field) ) )
133 /// dring
134 #define /*X*/ m_dring_link(p_ring, field, node) ( (typeof(p_ring))f_dring_link(&((p_ring)->field), &((node)->field), offsetof(typeof(*(p_ring)), field) ) )
135 /// ndring
136 #define /*X*/ m_ndring_link(p_ring, field, node) ( (typeof(p_ring))f_ndring_link(&((p_ring)->field), &((node)->field), offsetof(typeof(*(p_ring)), field) ) )
137 //@}
138 /**@name Unlink (macro)
139 * @memo Remove reference from this node.
140 * @doc
141 *  Because the holding pointer may reference the unlinked node, always set the ring
142 * holding pointer with the result of the call :
143 *  <pre>ring_ptr = m_ring_unlink(node, field);</pre>
144 *  It is highly recomanded to ensure that the node belongs to ring_ptr before calling
145 * the macro.
146 * @param p_ring (IN) The node you want to unlink.
147 * @param field (IN) the ring structure field name in the node structure.
148 * @return 0 the ring is empty, or the next node in the ring.
149 * @exception EMLINK null pointer found in ring link.
150 */

151 //@{
152 /// ring
153 #define /*X*/ m_ring_unlink(p_ring, field) ( (typeof(p_ring))f_ring_unlink(&((p_ring)->field), offsetof(typeof(*(p_ring)), field) ) )
154 /// nring
155 #define /*X*/ m_nring_unlink(p_ring, field) ( (typeof(p_ring))f_nring_unlink(&((p_ring)->field), offsetof(typeof(*(p_ring)), field) ) )
156 /// dring
157 #define /*X*/ m_dring_unlink(p_ring, field) ( (typeof(p_ring))f_dring_unlink(&((p_ring)->field), offsetof(typeof(*(p_ring)), field) ) )
158 /// ndring
159 #define /*X*/ m_ndring_unlink(p_ring, field) ( (typeof(p_ring))f_ndring_unlink(&((p_ring)->field), offsetof(typeof(*(p_ring)), field) ) )
160 //@}
161
162 /**@name Next (macro)
163 * @memo the next node.
164 * @doc
165 *   The macro expand as the next node of a node, allowing you to jump each node.
166 * Note that you have to provide a stop condition yourself when you loop around the ring.
167 * @param p_ring (IN) a pointer to structure node
168 * @param field (IN) the ring structure field name in the node structure.
169 * @return 0 the ring is empty, or the next node in the ring.
170 */

171 //@{
172 /// ring
173 #define /*X*/ m_ring_next(p_ring, field)   ((typeof(p_ring))((p_ring)?((char *)((p_ring)->field.next) -  offsetof(typeof(*(p_ring)), field) ) :0))
174 /// nring
175 #define /*X*/ m_nring_next(p_ring, field)  ((typeof(p_ring))((p_ring)?((char *)((p_ring)->field.next) -  offsetof(typeof(*(p_ring)), field) ) :0))
176 /// dring
177 #define /*X*/ m_dring_next(p_ring, field)  ((typeof(p_ring))((p_ring)?((char *)((p_ring)->field.next) -  offsetof(typeof(*(p_ring)), field) ) :0))
178 /// ndring
179 #define /*X*/ m_ndring_next(p_ring, field) ((typeof(p_ring))((p_ring)?((char *)((p_ring)->field.next) -  offsetof(typeof(*(p_ring)), field) ) :0))
180 //@}
181
182 /**@name List (macro)
183 * @memo the next node, with loop detection.
184 * @doc
185 *   The macro expand as the next node of a node, allowing you to jump each node.
186 *   If next node is ring parameter, it returns 0. This macro is switable for loops :
187 *
188 *     for (node = ring; !node; node = m_ring_list(list, node, brother) ) { ... }
189 *
190 * @param p_ring (IN) a pointer to structure node
191 * @param field (IN) the ring structure field name in the node structure.
192 * @return 0 the ring is empty, or the next node in the ring.
193 */

194 //@{
195 /// ring
196 #define /*X*/ m_ring_list(ring, node, field) ( (((node) = m_ring_next(node, field)) == (ring))?0:(node) )
197 /// nring
198 #define /*X*/ m_nring_list(ring, node, field) ( (((node) = m_nring_next(node, field)) == (ring))?0:(node) )
199 /// dring
200 #define /*X*/ m_dring_list(ring, node, field) ( (((node) = m_dring_next(node, field)) == (ring))?0:(node) )
201 /// ndring
202 #define /*X*/ m_ndring_list(ring, node, field) ( (((node) = m_ndring_next(node, field)) == (ring))?0:(node) )
203 //@}
204 /**@name Do, done (macro)
205 * @memo A loop macro construction helper.
206 * @doc
207 *   These to macros construct begin and end of loops to evry node in a ring :
208 *  <pre>m_ring_do(ring, node) ++i; m_ring_done(ring, node, field);</pre>
209 * count how many node there is in the ring.
210 * @param ring (IN) a pointer the ring ring
211 * @param var (IN) a variable pointer node beeing listed.
212 * @param field (IN) the ring structure field name in the node structure.
213 * @return 0 the ring is empty, or the next node in the ring.
214 */

215 //@{
216 /// ring, start loop
217 #define /*X*/ m_ring_do(ring, var) if ( ((var) = (ring)) ) do
218 /// ring, end loop
219 #define /*X*/ m_ring_done(ring, var, field) while ( (var) = m_ring_next((var), field), (var) != (ring) )
220 /// nring, start loop
221 #define /*X*/ m_nring_do(ring, var) if ( ((var) = (ring)) ) do
222 /// nring, end loop
223 #define /*X*/ m_nring_done(ring, var, field) while ( (var) = m_nring_next((var), field), (var) != (ring) )
224 /// dring, start loop
225 #define /*X*/ m_dring_do(ring, var) if ( ((var) = (ring)) ) do
226 /// dring, end loop
227 #define /*X*/ m_dring_done(ring, var, field) while ( (var) = m_dring_next((var), field), (var) != (ring) )
228 /// ndring, start loop
229 #define /*X*/ m_ndring_do(ring, var) if ( ((var) = (ring)) ) do
230 /// ndring, end loop
231 #define /*X*/ m_ndring_done(ring, var, field) while ( (var) = m_ndring_next((var), field), (var) != (ring) )
232 //@}
233 /**@name Find by name (macro)
234 * @memo For named ring, find a node with his name.
235 * @doc
236 * @param p_ring (IN) a pointer to your structure node
237 * @param field (IN) the ring structure field name in the node structure.
238 * @param name (IN) the node name.
239 * @return 0 the name is not found, the node if it is.
240 * @exception EMLINK null pointer found in ring link.
241 */

242 //@{
243 /// nring
244 #define /*X*/ m_nring_find(p_ring, field, name)  ( \
245   (typeof(p_ring))f_nring_find(&((p_ring)->field), (name), offsetof(typeof(*(p_ring)), field) ) )

246 /// ndring
247 #define /*X*/ m_ndring_find(p_ring, field, name)  ( \
248   (typeof(p_ring))f_ndring_find(&((p_ring)->field), (name), offsetof(typeof(*(p_ring)), field) ) )

249 //@}
250 /**@name Previous (macro)
251 * @memo For double ring, expand to previous node.
252 * @doc
253 * @param p_ring (IN) a pointer to your structure node
254 * @param field (IN) the ring structure field name in the node structure.
255 * @return 0 the ring is empty, or the previous node in the ring.
256 */

257 //@{
258 /// dring
259 #define /*X*/ m_dring_prev(p_ring, field)  ((typeof(p_ring))((p_ring)?((char *)((p_ring)->field.prev) -  offsetof(typeof(*(p_ring)), field) ) :0))
260 /// ndring
261 #define /*X*/ m_ndring_prev(p_ring, field) ((typeof(p_ring))((p_ring)?((char *)((p_ring)->field.prev) -  offsetof(typeof(*(p_ring)), field) ) :0))
262 //@}
263 /**@name Move (macro)
264 * @memo For double ring,jump n nodes back or force.
265 * @doc
266 * @param p_ring (IN) a pointer to your structure node
267 * @param hops (IN) Number of jumps.
268 * @param check (IN) if true, a loop detection.
269 * @param field (IN) the ring structure field name in the node structure.
270 * @return 0 the ring is empty, or the previous node in the ring.
271 * @exception ELOOP Move made a complete loop
272 * @exception EMLINK null pointer found in ring link.
273 */

274 //@{
275 /// nring
276 #define /*X*/ m_dring_move(p_ring, hops, check, field) ( \
277   (typeof(p_ring))f_dring_move(&((p_ring)->field), hops, check, offsetof(typeof(*(p_ring)), field) ) )

278 /// ndring
279 #define /*X*/ m_ndring_move(p_ring, hops, check, field) ( \
280   (typeof(p_ring))f_ndring_move(&((p_ring)->field), hops, check, offsetof(typeof(*(p_ring)), field) ) )

281 //@}
282 /**@name Errors
283 * @doc
284 *   When an error is detected, errno is used to give a minimal feed back. Errno values
285 * are given in each macro and function in there respectives manual entries at
286 * paragraphs "throws".
287 *  It is possible to customise error signaling by rewriting raise and relay macros
288 * in "config.h" file. This way, you could get textual reason.
289 *  See \URL[exception_stderr.h]{./src/exception_stderr.h.html}
290 * or \URL[exception_errno.h]{./src/exception_errno.h.html} for examples.
291 * @exception ELOOP Move made a complete loop (dring, ndring)
292 * @exception ENOTNAM Name is nil (nring, ndring).
293 * @exception ENAMETOOLONG Name is too long (nring, ndring).
294 * @exception EEXIST node is already in ring.
295 * @exception EMLINK null pointer found in ring link.
296 * @exception EFAULT node is nil.
297 */

298 //@{
299 //@}
300 /**@name Maintenance
301 */

302 //@{
303 /** @memo Set or get the check bit control on
304 * @doc
305 *   When check is on, the linkage integrity is checked each time a member
306 * function is called.
307 *   To get the curent check level, call with level at -1.
308 * @param level (IN) Only two levels : 0 or 1. -1 for read.
309 * @return curent check level.
310 */

311 int f_ring_check_opt(int level);
312 //@}
313 /**@name C API
314 * @memo The C fonctions set that implement rings
315 * @doc
316 *  The C API is less "friend user" than macros because more code have to be writen
317 * to call them properly.
318 *  In some situations where no member name can be provided to the macros for the ring
319 * datas they may be usefull.
320 * See \Ref{Implementation}
321 */

322 //@{
323 bool f_ring_selftest(struct s_ring *ring, size_t offset);
324 bool f_dring_selftest(struct s_dring *ring, size_t offset);
325 bool f_nring_selftest(struct s_nring *ring, size_t offset);
326 bool f_ndring_selftest(struct s_ndring *ring, size_t offset);
327
328 bool f_ring_is_in(struct s_ring *is, struct s_ring *in, size_t offset);
329 bool f_nring_is_in(struct s_nring *is, struct s_nring *in, size_t offset);
330 bool f_dring_is_in(struct s_dring *is, struct s_dring *in, size_t offset);
331 bool f_ndring_is_in(struct s_ndring *is, struct s_ndring *in, size_t offset);
332
333 void *f_ring_unlink(struct s_ring *node, size_t offset);
334 void *f_nring_unlink(struct s_nring *node, size_t offset);
335 void *f_dring_unlink(struct s_dring *node, size_t offset);
336 void *f_ndring_unlink(struct s_ndring *node, size_t offset);
337
338 void *f_ring_link(struct s_ring *ring, struct s_ring *_new, size_t offset);
339 void *f_nring_link(struct s_nring *ring, struct s_nring *_new, size_t offset);
340 void *f_dring_link(struct s_dring *ring, struct s_dring *_new, size_t offset);
341 void *f_ndring_link(struct s_ndring *ring, struct s_ndring *_new, size_t offset);
342
343 void *f_nring_find(struct s_nring *ring, const char *name, size_t offset);
344 void *f_ndring_find(struct s_ndring *ring, const char *name, size_t offset);
345
346 void *f_dring_move(struct s_dring *ring, int hops, bool check, size_t offset);
347 void *f_ndring_move(struct s_ndring *ring, int hops, bool check, size_t offset);
348 //@}
349
350 /*
351 struct s_ring *f_ring_next(struct s_ring *node);
352 struct s_ring *f_ring_link(struct s_ring *ring, struct s_ring *node);
353 struct s_ring *f_ring_unlink(struct s_ring *node);
354
355 struct s_nring *f_nring_next(struct s_nring *ring);
356 struct s_nring *f_nring_link(struct s_nring *ring, struct s_nring *new);
357 struct s_nring *f_nring_unlink(struct s_nring *node);
358 struct s_nring *f_nring_find(struct s_nring *ring, const char *name);
359
360 struct s_dring *f_dring_next(struct s_dring *ring);
361 struct s_dring *f_dring_prev(struct s_dring *ring);
362 struct s_dring *f_dring_move(struct s_dring *ring, int hops, bool check);
363
364 struct s_dring *f_dring_link(struct s_dring *ring, struct s_dring *new);
365 struct s_dring *f_dring_unlink(struct s_dring *node);
366 ** @memo Internal, expand to the ring structure adresse of a node.
367 * @doc
368 *   The macro expand as the next node of a node, allowing you to jump each node.
369 * Note that you have to provide a stop condition yourself when you loop around the ring.
370 * @param p_ring (IN) a pointer to structure node
371 * @param field (IN) the ring structure field name in the node structure.
372 * @return 0 the ring is empty, or the next node in the ring.
373 *
374 #define /*X*/ m_ring_to_container(p_ring, field) ((typeof(p_ring))((p_ring)?((char *)(p_ring) - offsetof(typeof(*(p_ring)), field) ) :0))
375
376
377 */

378
379 #endif /* ] _RING_H_ */


To rings Doc++

File Index

All Tags

Tags by File

Tags referrers

C to HTML Conversion by ctoohtml

Hosted by the courtesy of  
http://www.free.fr 
The stars ASAP english francais spanish
Durée du voyage intersidéral francais
Résolutions de l'ONU en HTML francais
Bussard Ramjet english francais
DWARF : dwarf2xml english
ELF : libelf examples english
Code presentation : ctoohtml english