e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information.
ab24932003-01-06Henrik Grubbström (Grubba) || $Id: cyclic.c,v 1.10 2003/01/06 17:20:59 grubba Exp $
e576bb2002-10-11Martin Nilsson */
1b10db2002-10-08Martin Nilsson 
24ddc71998-03-28Henrik Grubbström (Grubba) #include "global.h"
fc33451997-10-02Fredrik Hübinette (Hubbe) #include "cyclic.h"
ab24932003-01-06Henrik Grubbström (Grubba) RCSID("$Id: cyclic.c,v 1.10 2003/01/06 17:20:59 grubba Exp $");
24ddc71998-03-28Henrik Grubbström (Grubba) 
fc33451997-10-02Fredrik Hübinette (Hubbe) #define CYCLIC_HASH_SIZE 4711 CYCLIC *cyclic_hash[CYCLIC_HASH_SIZE];
545ca81997-10-07Fredrik Hübinette (Hubbe) static void low_unlink_cyclic(CYCLIC *c)
fc33451997-10-02Fredrik Hübinette (Hubbe) {
c7241b2000-08-10Henrik Grubbström (Grubba)  size_t h;
fc33451997-10-02Fredrik Hübinette (Hubbe)  CYCLIC **p;
ab24932003-01-06Henrik Grubbström (Grubba)  h=((char *)c->id)-(char *)0;
fc33451997-10-02Fredrik Hübinette (Hubbe)  h*=33;
ab24932003-01-06Henrik Grubbström (Grubba)  h|=((char *)c->a)-(char *)0;
fc33451997-10-02Fredrik Hübinette (Hubbe)  h*=33;
ab24932003-01-06Henrik Grubbström (Grubba)  h|=((char *)c->b)-(char *)0;
fc33451997-10-02Fredrik Hübinette (Hubbe)  h*=33;
ab24932003-01-06Henrik Grubbström (Grubba)  h|=((char *)c->th)-(char *)0;
fc33451997-10-02Fredrik Hübinette (Hubbe)  h*=33; h%=CYCLIC_HASH_SIZE; for(p=cyclic_hash+h;*p;p=&(p[0]->next)) { if(c == *p) { *p=c->next;
3b6bff2002-12-01Martin Stjernholm #ifdef CYCLIC_DEBUG fprintf (stderr, "%s: END_CYCLIC a=%p b=%p: no cycle\n", c->id, c->a, c->b); #endif
fc33451997-10-02Fredrik Hübinette (Hubbe)  return; } }
5aad932002-08-15Marcus Comstedt  Pike_fatal("Unlink cyclic on lost cyclic struct.\n");
fc33451997-10-02Fredrik Hübinette (Hubbe) }
545ca81997-10-07Fredrik Hübinette (Hubbe) void unlink_cyclic(CYCLIC *c) { UNSET_ONERROR(c->onerr); low_unlink_cyclic(c); }
fc33451997-10-02Fredrik Hübinette (Hubbe) void *begin_cyclic(CYCLIC *c,
3b6bff2002-12-01Martin Stjernholm  char *id,
fc33451997-10-02Fredrik Hübinette (Hubbe)  void *th, void *a, void *b) {
c7241b2000-08-10Henrik Grubbström (Grubba)  size_t h;
14bb592000-05-06Fredrik Hübinette (Hubbe)  void *ret=0;
fc33451997-10-02Fredrik Hübinette (Hubbe)  CYCLIC *p;
ab24932003-01-06Henrik Grubbström (Grubba)  h=((char *)id)-(char *)0;
fc33451997-10-02Fredrik Hübinette (Hubbe)  h*=33;
ab24932003-01-06Henrik Grubbström (Grubba)  h|=((char *)a)-(char *)0;
fc33451997-10-02Fredrik Hübinette (Hubbe)  h*=33;
ab24932003-01-06Henrik Grubbström (Grubba)  h|=((char *)b)-(char *)0;
fc33451997-10-02Fredrik Hübinette (Hubbe)  h*=33;
ab24932003-01-06Henrik Grubbström (Grubba)  h|=((char *)th)-(char *)0;
fc33451997-10-02Fredrik Hübinette (Hubbe)  h*=33; h%=CYCLIC_HASH_SIZE; for(p=cyclic_hash[h];p;p=p->next)
14bb592000-05-06Fredrik Hübinette (Hubbe)  {
fc33451997-10-02Fredrik Hübinette (Hubbe)  if(a == p->a && b==p->b && id==p->id)
14bb592000-05-06Fredrik Hübinette (Hubbe)  {
3b6bff2002-12-01Martin Stjernholm #ifdef CYCLIC_DEBUG fprintf (stderr, "%s: BEGIN_CYCLIC a=%p b=%p: found cycle\n", id, a, b); #endif
14bb592000-05-06Fredrik Hübinette (Hubbe)  ret=p->ret; break; } }
fc33451997-10-02Fredrik Hübinette (Hubbe) 
c7241b2000-08-10Henrik Grubbström (Grubba)  c->ret=(void *)(ptrdiff_t)1;
fc33451997-10-02Fredrik Hübinette (Hubbe)  c->a=a; c->b=b; c->id=id; c->th=th; c->next=cyclic_hash[h]; cyclic_hash[h]=c;
545ca81997-10-07Fredrik Hübinette (Hubbe)  SET_ONERROR(c->onerr, low_unlink_cyclic, c);
3b6bff2002-12-01Martin Stjernholm #ifdef CYCLIC_DEBUG if (!ret) fprintf (stderr, "%s: BEGIN_CYCLIC a=%p b=%p: no cycle\n", id, a, b); #endif
14bb592000-05-06Fredrik Hübinette (Hubbe)  return ret;
fc33451997-10-02Fredrik Hübinette (Hubbe) }