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.c


  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 #define /*X*/ _GNU_SOURCE
 16 #include <errno.h>
 17 #include <string.h>
 18
 19 #include "config.h"
 20 #include "exception.h"
 21 #include "ring.h"
 22
 23 /** @memo Hold check option. */
 24 static int /*X*/ check_opt;
 25 /** @memo Set or get check option.
 26 * @doc
 27 *  The check option provides integrity check on the ring on each call to
 28 * API funtions.
 29 * @param level (IN) 0 set to disable, 1 enable, -1 read curent value.
 30 * @return curent value.
 31 */

 32 int /*X*/ f_ring_check_opt(int level) { if ( level != -1 ) check_opt = level; return check_opt; }
 33
 34 /** @name Ring
 35 */

 36 //@{
 37 /** @memo Ring self integrity test
 38 * @doc
 39 *  Walk around the ring to check link ptrs.
 40 *  In most of the errors situation the functions will not give or even
 41 * cleanly return.
 42 * @param ring (IN) Ring to be checked
 43 * @param offset (IN) offset of structure s_ring
 44 * @return 1 if OK, 0 and errno if faulty.
 45 * @exception EMLINK null pointer found in ring link.
 46 */

 47 bool /*X*/ f_ring_selftest(struct s_ring *ring, size_t offset) {
 48   typeof(ring) r;
 49   if ( ring == (typeof(ring))offset ) return 1;
 50   for ( r = ring; r; r = r->next ) {
 51      if ( r == ring ) return 1;
 52   }
 53   excp_raise (return 0, EMLINK, "nul node found in ring");
 54 }
 55 /** @memo Test if an element is in a ring
 56 * @doc
 57 *  Return true if element is in.
 58 * @param is (IN) Element to search
 59 * @param in (IN) Ring
 60 * @param offset (IN) offset of structure s_ring
 61 * @return 1 if OK, 0 and errno if faulty.
 62 * @exception EFAULT is is nil.
 63 * @exception EMLINK null pointer found in ring link.
 64 */

 65 bool /*X*/ f_ring_is_in(struct s_ring *is, struct s_ring *in, size_t offset) {
 66   typeof(in) r;
 67   if ( is == (typeof(in))offset ) excp_raise(return 0, EFAULT, "is, is nil, indeed");
 68   if ( in == (typeof(in))offset ) return 0;
 69   if ( check_opt > 0 && !f_ring_selftest(in, offset) ) excp_relay (return 0, " ") ;
 70   r = in;
 71   do {
 72      if ( r == is ) return 1;
 73   } while ( r = r->next, r != in );
 74   return 0;
 75 }
 76 /** @memo Add a new element in the ring.
 77 * @doc
 78 *  Insert a new pearl in a ring.
 79 *  Return is always valid, even if ring is nil.
 80 * Be carefull if new can be nil, as you can lose the ring handle.
 81 * @param ring (IN) a pointer to ring part of a ring's node
 82 * @param new (IN) a pointer to the ring part of the node
 83 * @param offset (IN) the offset of the ring part in the node.
 84 * @return 0 the ring is empty, or the next node in the ring.
 85 * @exception EEXIST, new is already in ring.
 86 * @exception EFAULT new is nil.
 87 * @exception EMLINK null pointer found in ring link.
 88 */

 89 void * /*X*/ f_ring_link(struct s_ring *ring, struct s_ring *new, size_t offset) {
 90   if ( check_opt > 0 && !f_ring_selftest(ring, offset) == 0 ) excp_relay (return 0, "Memory jam");
 91
 92   if ( new == (typeof(ring))offset ) excp_raise (return 0, EFAULT, "new node is nil");
 93   if ( check_opt > 0 && f_ring_is_in(new, ring, offset) )
 94      excp_raise (return 0, EEXIST, "node is already in ring");
 95
 96   if ( ring == (typeof(ring))offset ) ring = new;
 97
 98   new->next = ring->next;
 99   ring->next = new;
100
101   return new?((char *)new - offset):0;
102 }
103 /** @memo Remove an element from a ring
104 * @doc
105 *   The ring is relinked to exclude the element.
106 * Return ptr is 0 if ring becomes empty.
107 * @param node (IN) a pointer to ring part of the node
108 * @param offset (IN) the offset of the ring part in the node.
109 * @return 0 the ring is empty, or the next node in the ring.
110 * @exception EMLINK null pointer found in ring link.
111 */

112 void * /*X*/ f_ring_unlink(struct s_ring *node, size_t offset) {
113   typeof(node) r;
114
115   if ( check_opt > 0 && !f_ring_selftest(node, offset) == 0) excp_relay (return 0, "Memory jam");
116   if ( node == (typeof(node))offset ) return 0;
117   if ( node == node->next ) return 0;
118
119   for ( r = node; r->next != node; r = r->next );
120   r->next = node->next;
121   node->next = 0;
122
123   return r?((char *)r - offset):0;
124 }
125 //@}
126 /** @name Named ring
127 */

128 //@{
129 /** @memo Name ring integrity test
130 * @doc
131 *  Walk around the ring to check link ptrs.
132 *  In most of the errors situation the functions will not give or even
133 * cleanly return.
134 * @param ring (IN) Ring to be checked
135 * @param offset (IN) offset of structure s_ring
136 * @return 1 if OK, 0 and errno if faulty.
137 * @exception EMLINK null pointer found in ring link.
138 */

139 bool /*X*/ f_nring_selftest(struct s_nring *ring, size_t offset) {
140   typeof(ring) r;
141   if ( ring == (typeof(ring))offset ) return 1;
142   for ( r = ring; r; r = r->next ) {
143      if ( r == ring ) return 1;
144   }
145   excp_raise (return 0, EMLINK, "nul node found in ring");
146 }
147 /** @memo Test if an element is in a ring
148 * @doc
149 *  Return true if element is in.
150 * @param is (IN) Element to search
151 * @param in (IN) Ring
152 * @param offset (IN) offset of structure s_ring
153 * @return 1 if OK, 0 and errno if faulty.
154 * @exception EFAULT is is nil.
155 * @exception EMLINK null pointer found in ring link.
156 */

157 bool /*X*/ f_nring_is_in(struct s_nring *is, struct s_nring *in, size_t offset) {
158   typeof(in) r;
159   if ( is == (typeof(in))offset ) excp_raise(return 0, EFAULT, "is, is nil, indeed");
160   if ( in == (typeof(in))offset ) return 0;
161   if ( check_opt > 0 && !f_nring_selftest(in, offset) ) excp_relay (return 0, " ") ;
162   r = in;
163   do {
164      if ( r == is ) return 1;
165   } while ( r = r->next, r != in );
166   return 0;
167 }
168 /** @memo Find a node in a named ring by its name.
169 * @doc
170 *   Names are limited to 1000 bytes.
171 * @param ring (IN) a pointer to ring part of a ring's node
172 * @param name (IN) name to look for
173 * @param offset (IN) the offset of the ring part in the node.
174 * @return 0 the ring is not found, or a node.
175 * @exception EMLINK null pointer found in ring link.
176 */

177 void * /*X*/ f_nring_find(struct s_nring *ring, const char *name, size_t offset) {
178   typeof(ring) r;
179   if ( check_opt > 0 && !f_nring_selftest(ring, offset) == 0) excp_relay (return 0, " ");
180   if ( ring == (typeof(ring))offset ) return 0;
181
182   for ( r = ring->next; r && strncmp(r->name, name, 1000); r = r->next ) {
183      if ( r == ring ) return 0;
184   }
185   return (r)?((char *)r - offset):0;
186 }
187 /** @memo Add a new element in the ring.
188 * @doc
189 *  Insert a new pearl in a ring.
190 *  Return is always valid, even if ring is nil.
191 * Be carefull if new can be nil, as you can lose the ring handle.
192 * @param ring (IN) a pointer to ring part of a ring's node
193 * @param new (IN) a pointer to the ring part of the node
194 * @param offset (IN) the offset of the ring part in the node.
195 * @return 0 the ring is empty, or the next node in the ring.
196 * @exception ENOTNAM, Name is nil.
197 * @exception ENAMETOOLONG, Name is too long.
198 * @exception EEXIST, new is already in ring.
199 * @exception EFAULT new is nil.
200 * @exception EMLINK null pointer found in ring link.
201 */

202 void * /*X*/ f_nring_link(struct s_nring *ring, struct s_nring *new, size_t offset) {
203   if ( check_opt > 0 && !f_nring_selftest(ring, offset) == 0 ) excp_relay (return 0, "Memory jam");
204
205   if ( new == (typeof(ring))offset ) excp_raise (return 0, EFAULT, "new node is nil");
206   if ( !new->name ) excp_raise (return 0, ENOTNAM, "new node name is nil");
207   if ( strnlen(new->name, 1000) == 1000 ) excp_raise (return 0, ENAMETOOLONG, "new node name is too long");
208   if ( check_opt > 0 && f_nring_is_in(new, ring, offset) )
209      excp_raise (return 0, EEXIST, "node is already in ring");
210   if ( f_nring_find(ring, new->name, offset) )
211      excp_raise(return 0, ENOTUNIQ, "A node named \"%s\" already exists",new->name);
212
213   if ( ring == (typeof(ring))offset ) ring = new;
214
215   new->next = ring->next;
216   ring->next = new;
217
218   return new?((char *)new - offset):0;
219 }
220 /** @memo Remove an element from a ring
221 * @doc
222 *   The ring is relinked to exclude the element.
223 * Return ptr is 0 if ring becomes empty.
224 * @param node (IN) a pointer to ring part of the node
225 * @param offset (IN) the offset of the ring part in the node.
226 * @return 0 the ring is empty, or the next node in the ring.
227 * @exception EMLINK null pointer found in ring link.
228 */

229 void * /*X*/ f_nring_unlink(struct s_nring *node, size_t offset) {
230   typeof(node) r;
231
232   if ( check_opt > 0 && !f_nring_selftest(node, offset) == 0) excp_relay (return 0, "Memory jam");
233   if ( node == (typeof(node))offset ) return 0;
234   if ( node == node->next ) return 0;
235
236   for ( r = node; r->next != node; r = r->next );
237   r->next = node->next;
238
239   return r?((char *)r - offset):0;
240 }
241 //@}
242
243 /** @name Double linked ring
244 */

245 //@{
246 /** @memo Ring integrity test
247 * @doc
248 *  Walk around the ring to check link ptrs.
249 *  In most of the errors situation the functions will not give or even
250 * cleanly return.
251 * @param ring (IN) Ring to be checked
252 * @param offset (IN) offset of structure s_ring
253 * @return 1 if OK, 0 and errno if faulty.
254 * @exception EMLINK null pointer found in ring link.
255 */

256 bool /*X*/ f_dring_selftest(struct s_dring *ring, size_t offset) {
257   typeof(ring) r;
258
259   if ( ring == (typeof(ring))offset ) return 1;
260   
261   for ( r = ring; r; r = r->next ) {
262      if ( !r->next ) break;
263      if ( !r->prev ) break;
264      if ( r->next->prev != r || r->prev->next != r)
265         excp_raise (return 0, EMLINK, "Broken link for node %p", r);
266      if ( r == ring ) return 1;
267   }
268   excp_raise (return 0, EMLINK, "Nul link found in node %p", r);
269 }
270 /** @memo Test if an element is in a ring
271 * @doc
272 *  Return true if element is in.
273 * @param is (IN) Element to search
274 * @param in (IN) Ring
275 * @param offset (IN) offset of structure s_ring
276 * @return 1 if OK, 0 and errno if faulty.
277 * @exception EFAULT is is nil.
278 * @exception EMLINK null pointer found in ring link.
279 */

280 bool /*X*/ f_dring_is_in(struct s_dring *is, struct s_dring *in, size_t offset) {
281   typeof(in) r;
282   if ( is == (typeof(in))offset ) excp_raise(return 0, EFAULT, "is, is nil, indeed");
283   if ( in == (typeof(in))offset ) return 0;
284   if ( check_opt > 0 && !f_dring_selftest(in, offset) ) excp_relay (return 0, " ") ;
285   r = in;
286   do {
287      if ( r == is ) return 1;
288   } while ( r = r->next, r != in );
289   return 0;
290 }
291 /** @memo Return +/- nth node frome curent
292 * @doc
293 *  Provide a abitrary position displacement in a ring. It is probably
294 * usefull only for small values of hop counts (1 or -1), as ring order
295 * does not matter.
296 * @param ring (IN) a pointer to ring part of a ring's node
297 * @param hops (IN) number of hops to move
298 * @param check (IN) Check circular overshoot
299 * @param offset (IN) the offset of the ring part in the node.
300 * @return 0 the ring is empty or check error, node at pos + hops in the ring.
301 * @exception ELOOP Move made a complete loop
302 * @exception EMLINK null pointer found in ring link.
303 */

304 void * /*X*/ f_dring_move(struct s_dring *ring, int hops, bool check, size_t offset) {
305   typeof(ring) r = ring;
306
307   if ( ring == (typeof(ring))offset || !hops ) return (char *)ring -offset;
308   if ( check_opt > 0 && !f_dring_selftest(ring, offset) ) excp_relay (return 0, " ") ;
309   if ( hops > 0 ) {
310      for ( r = ring->next, --hops; hops; --hops, r = r->next ) {
311         if ( check && r->next == ring ) excp_raise( return (void *) -offset, ELOOP, "Move made a complete loop");
312      }
313      return (char *)r - offset;
314   }
315   for ( r = ring->prev, ++hops; hops; ++hops, r = r->prev ) {
316      if ( check && r->prev == ring ) excp_raise( return (void *) -offset, ELOOP, "Move made a complete loop");
317   }
318   return (char *)r - offset;
319 }
320 /** @memo Add a new element in the ring.
321 * @doc
322 *  Insert a new pearl in a ring.
323 *  Return is always valid, even if ring is nil.
324 * Be carefull if new can be nil, as you can lose the ring handle.
325 * @param ring (IN) a pointer to ring part of a ring's node
326 * @param new (IN) a pointer to the ring part of the node
327 * @param offset (IN) the offset of the ring part in the node.
328 * @return 0 the ring is empty, or the next node in the ring.
329 * @exception EEXIST, new is already in ring.
330 * @exception EFAULT new is nil.
331 * @exception EMLINK null pointer found in ring link.
332 */

333 void * /*X*/ f_dring_link(struct s_dring *ring, struct s_dring *new, size_t offset) {
334   if ( check_opt > 0 && !f_dring_selftest(ring, offset) == 0 ) excp_relay (return 0, " ");
335   if ( new == (typeof(ring))offset ) excp_raise (return 0, EFAULT, "new node is nil");
336   if ( check_opt > 0 && f_dring_is_in(new, ring, offset) )
337      excp_raise (return 0, EEXIST, "node is already in ring");
338   if ( ring == (typeof(ring))offset ) ring = new;
339
340   new->next = ring->next;
341   new->prev = ring;
342   ring->next = new;
343   new->next->prev = new;
344
345   return new?((char *)new - offset):0;
346 }
347 /** @memo Remove an element from a ring
348 * @doc
349 *   The ring is relinked to exclude the element.
350 * Return ptr is 0 if ring becomes empty.
351 * @param node (IN) a pointer to ring part of the node
352 * @param offset (IN) the offset of the ring part in the node.
353 * @return 0 the ring is empty, or the next node in the ring.
354 * @exception EMLINK null pointer found in ring link.
355 */

356 void * /*X*/ f_dring_unlink(struct s_dring *node, size_t offset) {
357   if ( node == (typeof(node))offset ) return 0; /* node = 0 */
358
359   /* AZT sam, 09 mai 2009 13:00:46 +0200
360   if ( node == (typeof(node))offset ) return 0; */

361   if ( check_opt > 0 && !f_dring_selftest(node, offset) == 0) excp_relay (return 0, " ");
362   if ( node == node->next ) return 0;
363
364   node->prev->next = node->next;
365   node->next->prev = node->prev;
366
367   return node?((char *)node->prev - offset):0;
368 }
369 //@}
370
371 /** @name Double linked named ring
372 */

373 //@{
374 /** @memo Ring integrity test
375 * @doc
376 *  Walk around the ring to check link ptrs.
377 *  In most of the errors situation the functions will not give or even
378 * cleanly return.
379 * @param ring (IN) Ring to be checked
380 * @param offset (IN) offset of structure s_ring
381 * @return 1 if OK, 0 and errno if faulty.
382 * @exception EMLINK null pointer found in ring link.
383 */

384 bool /*X*/ f_ndring_selftest(struct s_ndring *ring, size_t offset) {
385   typeof(ring) r;
386
387   if ( ring == (typeof(ring))offset ) return 1;
388   
389   for ( r = ring; r; r = r->next ) {
390      if ( !r->next ) break;
391      if ( !r->prev ) break;
392      if ( r->next->prev != r || r->prev->next != r)
393         excp_raise (return 0, EMLINK, "Broken link for node %p", r);
394      if ( r == ring ) return 1;
395   }
396   excp_raise (return 0, EMLINK, "Nul link found in node %p", r);
397 }
398 /** @memo Test if an element is in a ring
399 * @doc
400 *  Return true if element is in.
401 * @param is (IN) Element to search
402 * @param in (IN) Ring
403 * @param offset (IN) offset of structure s_ring
404 * @return 1 if OK, 0 and errno if faulty.
405 * @exception EFAULT is is nil.
406 * @exception EMLINK null pointer found in ring link.
407 */

408 bool /*X*/ f_ndring_is_in(struct s_ndring *is, struct s_ndring *in, size_t offset) {
409   typeof(in) r;
410   if ( is == (typeof(in))offset ) excp_raise(return 0, EFAULT, "is, is nil, indeed");
411   if ( in == (typeof(in))offset ) return 0;
412   if ( check_opt > 0 && !f_ndring_selftest(in, offset) ) excp_relay (return 0, " ") ;
413   r = in;
414   do {
415      if ( r == is ) return 1;
416   } while ( r = r->next, r != in );
417   return 0;
418 }
419
420 /** @memo Return +/- nth node frome curent
421 * @doc
422 *  Provide a abritrary position displacement in a ring. It is probably
423 * usefull only for small values of hop counsts (1 or -1), as ring order
424 * does not matter.
425 * @param ring (IN) a pointer to ring part of a ring's node
426 * @param hops (IN) number of hops to move
427 * @param check (IN) Check circular overshoot
428 * @param offset (IN) the offset of the ring part in the node.
429 * @return 0 the ring is empty or check error, node at pos + hops in the ring.
430 * @exception ELOOP Move made a complete loop
431 * @exception EMLINK null pointer found in ring link.
432 */

433 void * /*X*/ f_ndring_move(struct s_ndring *ring, int hops, bool check, size_t offset) {
434   typeof(ring) r = ring;
435
436   if ( ring == (typeof(ring))offset || !hops ) return (char *)ring -offset;
437   if ( check_opt > 0 && !f_ndring_selftest(ring, offset) ) excp_relay (return 0, " ") ;
438   if ( hops > 0 ) {
439      for ( r = ring->next, --hops; hops; --hops, r = r->next ) {
440         if ( check && r->next == ring ) excp_raise( return (void *) -offset, ELOOP, "Move made a complete loop");
441      }
442      return (char *)r - offset;
443   }
444   for ( r = ring->prev, ++hops; hops; ++hops, r = r->prev ) {
445      if ( check && r->prev == ring ) excp_raise( return (void *) -offset, ELOOP, "Move made a complete loop");
446   }
447   return (char *)r - offset;
448 }
449 /** @memo Find a node in a named ring by its name.
450 * @doc
451 *   Names are limited to 1000 bytes.
452 * @param ring (IN) a pointer to ring part of a ring's node
453 * @param name (IN) name to look for
454 * @param offset (IN) the offset of the ring part in the node.
455 * @return 0 the ring is not found, or a node.
456 * @exception EMLINK null pointer found in ring link.
457 */

458 void * /*X*/ f_ndring_find(struct s_ndring *ring, const char *name, size_t offset) {
459   typeof(ring) r;
460   if ( check_opt > 0 && !f_ndring_selftest(ring, offset) == 0) excp_relay (return 0, " ");
461   if ( ring == (typeof(ring))offset ) return 0;
462
463   for ( r = ring->next; r && strncmp(r->name, name, 1000); r = r->next ) {
464      if ( r == ring ) return 0;
465   }
466   return (r)?((char *)r - offset):0;
467 }
468 /** @memo Add a new element in the ring.
469 * @doc
470 *  Insert a new pearl in a ring.
471 *  Return is always valid, even if ring is nil.
472 * Be carefull if new can be nil, as you can lose the ring handle.
473 * @param ring (IN) a pointer to ring part of a ring's node
474 * @param new (IN) a pointer to the ring part of the node
475 * @param offset (IN) the offset of the ring part in the node.
476 * @return 0 the ring is empty, or the next node in the ring.
477 * @exception ENOTNAM, Name is nil.
478 * @exception ENAMETOOLONG, Name is too long.
479 * @exception EEXIST, new is already in ring.
480 * @exception EFAULT new is nil.
481 * @exception EMLINK null pointer found in ring link.
482 */

483 void * /*X*/ f_ndring_link(struct s_ndring *ring, struct s_ndring *new, size_t offset) {
484   if ( check_opt > 0 && !f_ndring_selftest(ring, offset) == 0 ) excp_relay (return 0, " ");
485   if ( new == (typeof(ring))offset ) excp_raise (return 0, EFAULT, "new node is nil");
486   if ( !new->name ) excp_raise (return 0, ENOTNAM, "new node name is nil");
487   if ( strnlen(new->name, 1000) == 1000 ) excp_raise (return 0, ENAMETOOLONG, "new node name is too long");
488   if ( check_opt > 0 && f_ndring_is_in(new, ring, offset) )
489      excp_raise (return 0, EEXIST, "node is already in ring");
490   if ( f_ndring_find(ring, new->name, offset) )
491      excp_raise(return 0, ENOTUNIQ, "A node named \"%s\" already exists",new->name);
492
493   if ( ring == (typeof(ring))offset ) ring = new;
494
495   new->next = ring->next;
496   new->prev = ring;
497   ring->next = new;
498   new->next->prev = new;
499
500   return new?((char *)new - offset):0;
501 }
502 /** @memo Remove an element from a ring
503 * @doc
504 *   The ring is relinked to exclude the element.
505 * Return ptr is 0 if ring becomes empty.
506 * @param node (IN) a pointer to ring part of the node
507 * @param offset (IN) the offset of the ring part in the node.
508 * @return 0 the ring is empty, or the next node in the ring.
509 * @exception EMLINK null pointer found in ring link.
510 */

511 void * /*X*/ f_ndring_unlink(struct s_ndring *node, size_t offset) {
512   if ( node == (typeof(node))offset ) node = 0;
513
514   if ( node == (typeof(node))offset ) return 0;
515   if ( check_opt > 0 && !f_ndring_selftest(node, offset) == 0) excp_relay (return 0, " ");
516   if ( node == node->next ) return 0;
517
518   node->prev->next = node->next;
519   node->next->prev = node->prev;
520
521   return node?((char *)node->prev - offset):0;
522 }
523
524 //@}
525


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