comparison src/ploki/venus.c @ 4223:ac0403686959

<oerjan> rm -rf src/ploki; mv ploki src
author HackBot
date Fri, 20 Dec 2013 22:18:50 +0000
parents
children
comparison
equal deleted inserted replaced
4222:b0f3e267bb1e 4223:ac0403686959
1 #include "Str.h"
2 #include "hash.h"
3 #include "op.h"
4 #include "venus.h"
5 #include "xmalloc.h"
6 #include "zz.h"
7
8 #include <stddef.h>
9 #include <stdio.h>
10 #include <string.h>
11
12 enum {MAGIC = 23};
13
14 struct sorted {
15 size_t size, length;
16 struct op **array;
17 };
18
19 static size_t hash(const void *p, size_t seed) {
20 return St_hash(p, seed);
21 }
22
23 static int compar(const void *a, const void *b) {
24 return St_cmp(a, b);
25 }
26
27 static void delk(void *k) {
28 St_clear(k);
29 xfree(k);
30 }
31
32 static void delv(void *v) {
33 xfree(((struct sorted *)v)->array);
34 xfree(v);
35 }
36
37 void ve_init(struct venus *v) {
38 h_init(&v->table, hash, compar, delk, delv);
39 }
40
41 void ve_end(struct venus *v) {
42 h_end(&v->table);
43 }
44
45 void ve_enter(struct venus *v, const String *s, struct op *o) {
46 struct sorted *x;
47 void *tmp;
48 size_t a, z;
49
50 if (h_get(&v->table, s, &tmp) == H_NOENT) {
51 String *label;
52 x = xmalloc(1, sizeof *x);
53 x->array = xmalloc(x->size = MAGIC, sizeof *x->array);
54 x->array[0] = o;
55 x->length = 1;
56 label = xmalloc(1, sizeof *label);
57 St_init(label);
58 St_cpy(label, s);
59 h_put(&v->table, label, x, 1);
60 return;
61 }
62 x = tmp;
63
64 for (a = 0, z = x->length; a < z; ) {
65 if (x->array[(a + z) / 2]->line < o->line) {
66 a = (a + z) / 2 + 1u;
67 } else if (x->array[(a + z) / 2]->line > o->line) {
68 z = (a + z) / 2;
69 } else {
70 NOTREACHED;
71 }
72 }
73
74 if (x->length >= x->size) {
75 x->array = xrealloc(x->array, x->size *= 2);
76 }
77 memmove(x->array + a + 1u, x->array + a, x->length - a);
78 x->array[a] = o;
79 x->length++;
80 }
81
82 struct op *ve_findnext(struct venus *v, const String *s, size_t line) {
83 struct sorted *x;
84 void *tmp;
85 size_t a, z;
86
87 if (h_get(&v->table, s, &tmp) == H_NOENT) {
88 return NULL;
89 }
90 x = tmp;
91
92 for (a = 0, z = x->length; a < z; ) {
93 if (x->array[(a + z) / 2]->line < line) {
94 a = (a + z) / 2 + 1u;
95 } else if (x->array[(a + z) / 2]->line > line) {
96 z = (a + z) / 2;
97 } else {
98 a = (a + z) / 2 + 1u;
99 break;
100 }
101 }
102
103 return x->array[a % x->length];
104 }
105
106 struct op *ve_findprev(struct venus *v, const String *s, size_t line) {
107 struct sorted *x;
108 void *tmp;
109 size_t a, z;
110
111 if (h_get(&v->table, s, &tmp) == H_NOENT) {
112 return NULL;
113 }
114 x = tmp;
115
116 for (a = 0, z = x->length; a < z; ) {
117 if (x->array[(a + z) / 2]->line < line) {
118 a = (a + z) / 2 + 1u;
119 } else if (x->array[(a + z) / 2]->line > line) {
120 z = (a + z) / 2;
121 } else {
122 a = (a + z) / 2;
123 break;
124 }
125 }
126 a += x->length - 1u;
127 return x->array[a % x->length];
128 }
129
130 const String *ve_label(struct venus *v, const struct op *op) {
131 void *key, *value;
132
133 h_reset(&v->table);
134 while (h_nextkv(&v->table, &key, &value) == H_OK) {
135 const struct sorted *x = value;
136 size_t i;
137
138 for (i = 0; i < x->length; ++i) {
139 if (x->array[i] == op) {
140 return key;
141 }
142 }
143 }
144
145 return NULL;
146 }