1 | | |
2 | | |
3 | | |
4 | | |
5 | | |
6 | | |
7 | | |
8 | | |
9 | | |
10 | | |
11 | | |
12 | | |
13 | | |
14 | | |
15 | | |
16 | | |
17 | | |
18 | | |
19 | | |
20 | | |
21 | | |
22 | | |
23 | | |
24 | | |
25 | | |
26 | | |
27 | | |
28 | | |
29 | | |
30 | | |
31 | | |
32 | | |
33 | | |
34 | | |
35 | | |
36 | | |
37 | | |
38 | | |
39 | | |
40 | | |
41 | | |
42 | | |
43 | | |
44 | | |
45 | | |
46 | | |
47 | | |
48 | | |
49 | | |
50 | | |
51 | | |
52 | | |
53 | | |
54 | | |
55 | | |
56 | | |
57 | | |
58 | | |
59 | | |
60 | | |
61 | | |
62 | | |
63 | | |
64 | | |
65 | | |
66 | | |
67 | | |
68 | | |
69 | | |
70 | | |
71 | | |
72 | | |
73 | | |
74 | | |
75 | | |
76 | | |
77 | | |
78 | | |
79 | | |
80 | | |
81 | | |
82 | | |
83 | | |
84 | | |
85 | | |
86 | | |
87 | | |
88 | | |
89 | | |
90 | | |
91 | | |
92 | | |
93 | | |
94 | | |
95 | | |
96 | | |
97 | | |
| | | | | | | | #include "global.h" | #include "cyclic.h" | | RCSID("$Id: cyclic.c,v 1.11 2003/06/30 17:06:08 mast Exp $"); | | #define CYCLIC_HASH_SIZE 4711 | | CYCLIC *cyclic_hash[CYCLIC_HASH_SIZE]; | | static void low_unlink_cyclic(CYCLIC *c) | { | size_t h; | CYCLIC **p; | h=PTR_TO_INT(c->id); | h*=33; | h|=PTR_TO_INT(c->a); | h*=33; | h|=PTR_TO_INT(c->b); | h*=33; | h|=PTR_TO_INT(c->th); | h*=33; | h%=CYCLIC_HASH_SIZE; | | for(p=cyclic_hash+h;*p;p=&(p[0]->next)) | { | if(c == *p) | { | *p=c->next; | #ifdef CYCLIC_DEBUG | fprintf (stderr, "%s: END_CYCLIC a=%p b=%p: no cycle\n", c->id, c->a, c->b); | #endif | return; | } | } | Pike_fatal("Unlink cyclic on lost cyclic struct.\n"); | } | | void unlink_cyclic(CYCLIC *c) | { | UNSET_ONERROR(c->onerr); | low_unlink_cyclic(c); | } | | void *begin_cyclic(CYCLIC *c, | char *id, | void *th, | void *a, | void *b) | { | size_t h; | void *ret=0; | CYCLIC *p; | | h=PTR_TO_INT(id); | h*=33; | h|=PTR_TO_INT(a); | h*=33; | h|=PTR_TO_INT(b); | h*=33; | h|=PTR_TO_INT(th); | h*=33; | h%=CYCLIC_HASH_SIZE; | | for(p=cyclic_hash[h];p;p=p->next) | { | if(a == p->a && b==p->b && id==p->id) | { | #ifdef CYCLIC_DEBUG | fprintf (stderr, "%s: BEGIN_CYCLIC a=%p b=%p: found cycle\n", id, a, b); | #endif | ret=p->ret; | break; | } | } | | c->ret=(void *)(ptrdiff_t)1; | c->a=a; | c->b=b; | c->id=id; | c->th=th; | c->next=cyclic_hash[h]; | cyclic_hash[h]=c; | SET_ONERROR(c->onerr, low_unlink_cyclic, c); | #ifdef CYCLIC_DEBUG | if (!ret) fprintf (stderr, "%s: BEGIN_CYCLIC a=%p b=%p: no cycle\n", id, a, b); | #endif | return ret; | } | | |
|