Hosted by the courtesy of  
 GitHub 
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  
 GitHub 
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