Mercurial > ~dholland > hg > ag > index.cgi
comparison anagram/agcore/tsd.cpp @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:13d2b8934445 |
---|---|
1 /* | |
2 * AnaGram, A System for Syntax Directed Programming | |
3 * Copyright 1993-2002 Parsifal Software. All Rights Reserved. | |
4 * See the file COPYING for license and usage terms. | |
5 * | |
6 * tsd.cpp - tuple set dictionary | |
7 */ | |
8 | |
9 #include <stdarg.h> | |
10 #include <string.h> | |
11 #include "port.h" | |
12 | |
13 #include "assert.h" | |
14 #include "myalloc.h" | |
15 #include "tsd.h" | |
16 | |
17 //#define INCLUDE_LOGGING | |
18 #include "log.h" | |
19 | |
20 | |
21 /* | |
22 invalid_tsd() checks the internal consistency of a tuple set and | |
23 returns true if the tuple set is invalid | |
24 */ | |
25 | |
26 int invalid_tsd(tsd *t) { | |
27 if (!ptr_ok(t)) return 1; | |
28 if (t->nt > t->na) return 1; | |
29 if (t->sb == NULL) return 0; | |
30 return !ptr_ok(t->sb); | |
31 } | |
32 | |
33 void purge_tsd(tsd *r, tsd *k) { | |
34 LOGSECTION("purge_tsd"); | |
35 int *rp = r->sb; | |
36 int *wp = rp; | |
37 int wn = 0; | |
38 int rn = r->nt; | |
39 int rw = r->tw; | |
40 int *kp = k->sb; | |
41 int kn = k->nt; | |
42 int kw = k->tw; | |
43 | |
44 LOGV(r->nt) LCV(k->nt); | |
45 check_tsd(r); | |
46 check_tsd(k); | |
47 assert (kw == rw); | |
48 while (rn--) { | |
49 int *sp = kp; | |
50 int sn = kn; | |
51 | |
52 #ifdef INCLUDE_LOGGING | |
53 LOGS("Contains "); | |
54 for (int k = 0; k < kw; k++) LOGX() LS(rp[k]); | |
55 #endif | |
56 | |
57 while (sn--) { | |
58 int k = rw; | |
59 while (k--) { | |
60 if (rp[k] != sp[k]) break; | |
61 } | |
62 if (k < 0) break; | |
63 sp += kw; | |
64 } | |
65 if (sn < 0) { | |
66 if (wp != rp) { | |
67 int k = rw; | |
68 while (k--) { | |
69 wp[k] = rp[k]; | |
70 } | |
71 } | |
72 wp += rw; | |
73 wn++; | |
74 } | |
75 #ifdef INCLUDE_LOGGING | |
76 else { | |
77 LOGS("Eliminating"); | |
78 for (int k = 0; k < kw; k++) (*Log::theLog) LS(rp[k]); | |
79 } | |
80 #endif | |
81 rp += rw; | |
82 } | |
83 r->nt = wn; | |
84 } | |
85 | |
86 void p1_tsd(tsd *r, int rc, tsd *k, int kc) { | |
87 int *rp = r->sb; | |
88 int *wp = rp; | |
89 int wn = 0; | |
90 int rn = r->nt; | |
91 int rw = r->tw; | |
92 int *kp = k->sb; | |
93 int kn = k->nt; | |
94 int kw = k->tw; | |
95 | |
96 check_tsd(k); | |
97 while (rn--) { | |
98 int *sp = kp; | |
99 int sn = kn; | |
100 int tv = rp[rc]; | |
101 | |
102 while (sn--) { | |
103 if (tv == sp[kc]) break; | |
104 sp += kw; | |
105 } | |
106 if (sn < 0) { | |
107 if (wp != rp) { | |
108 int k = rw; | |
109 while (k--) { | |
110 wp[k] = rp[k]; | |
111 } | |
112 } | |
113 wp += rw; | |
114 wn++; | |
115 } | |
116 rp += rw; | |
117 } | |
118 r->nt = wn; | |
119 } | |
120 | |
121 /* | |
122 copy_tuple_set makes a copy of a tuple set, including a copy | |
123 of the contents | |
124 */ | |
125 | |
126 tsd *copy_tuple_set(tsd *t) { | |
127 tsd *c; | |
128 unsigned n; | |
129 | |
130 check_tsd(t); | |
131 c = ZALLOCATE(1,tsd); | |
132 n = t->na * t->tw; | |
133 c->sb = ALLOCATE(n, int); | |
134 if (n) { | |
135 memmove(c->sb,t->sb, n*sizeof(*t->sb)); | |
136 } | |
137 c->nt = t->nt; | |
138 c->tw = t->tw; | |
139 c->na = t->na; | |
140 return c; | |
141 } | |
142 | |
143 tsd *delete_tsd(tsd *ts) { | |
144 if (ts == NULL) { | |
145 return NULL; | |
146 } | |
147 assert(ts->nt <= ts->na); | |
148 if (ts->sb != NULL) { | |
149 DEALLOCATE(ts->sb); | |
150 } | |
151 DEALLOCATE(ts); | |
152 return NULL; | |
153 } | |
154 | |
155 void reset_tsd(tsd *ts) { | |
156 unsigned na,tw; | |
157 unsigned k; | |
158 | |
159 check_tsd(ts); | |
160 assert(ts->nt <= ts->na); | |
161 if (ts->nt == 0) { | |
162 if (ts->sb == NULL) { | |
163 return; | |
164 } | |
165 } | |
166 tw = ts->tw; | |
167 na = ts->na; | |
168 ts->nt = 0; | |
169 ok_ptr(ts->sb); | |
170 k = tw*na*sizeof(*ts->sb); | |
171 size_ok(ts->sb, k, __FILE__, __LINE__); | |
172 memset(ts->sb, 0, k); | |
173 } | |
174 | |
175 tsd *spec_tsd(unsigned size, unsigned n) { | |
176 tsd *ts; | |
177 | |
178 ts = ZALLOCATE(1, tsd); | |
179 ok_ptr(ts); | |
180 ts->tw = n; | |
181 if (size == 0) { | |
182 return ts; | |
183 } | |
184 ts->na = size; | |
185 ts->sb = ZALLOCATE(size*ts->tw, int); | |
186 return ts; | |
187 } | |
188 | |
189 tsd *resize_tsd(tsd *ts, unsigned size) { | |
190 LOGSECTION("resize_tsd"); | |
191 unsigned lim; | |
192 | |
193 ok_ptr(ts); | |
194 if (size == ts->na) { | |
195 return ts; | |
196 } | |
197 | |
198 lim = (unsigned) MAX_BYTES/(ts->tw * sizeof(*ts->sb)); | |
199 if (size > lim) { | |
200 size = lim; | |
201 } | |
202 LOGV(ts->nt) LCV(size); | |
203 | |
204 assert(ts->nt <= size); | |
205 ts->sb = reallocate(ts->sb,ts->tw*size, int); | |
206 ts->na = size; | |
207 return ts; | |
208 } | |
209 | |
210 tsd *init_tsd(unsigned n) { | |
211 tsd *ts; | |
212 | |
213 ts = spec_tsd(32,n); | |
214 return ts; | |
215 } | |
216 | |
217 int sit(tsd *t,...) { | |
218 va_list ap; | |
219 int *sp,*p; | |
220 unsigned i,j; | |
221 unsigned long size; | |
222 unsigned long lim; | |
223 unsigned nt,tw,nb; | |
224 int flag; | |
225 | |
226 check_stack; | |
227 check_tsd(t); | |
228 if (t->nt >= t->na) { | |
229 if (t->na == 0) { | |
230 size = 32; | |
231 } | |
232 else if (t->na > ((MAX_BYTES/2)/3)) { | |
233 size = MAX_BYTES; | |
234 } | |
235 else { | |
236 size = 1 + t->na + t->na/2; | |
237 } | |
238 | |
239 lim = MAX_BYTES/(t->tw * sizeof(*t->sb)); | |
240 if (size > lim) size = lim; | |
241 LOGSECTION("sit::resize"); | |
242 LOGV(t->nt) LCV(size); | |
243 assert(t->nt < size); | |
244 | |
245 t->sb = reallocate(t->sb,t->tw*(unsigned)size, int); | |
246 t->na = (unsigned) size; | |
247 } | |
248 | |
249 va_start(ap,t); | |
250 sp = t->sb + t->tw * t->nt; | |
251 for (i = 0; i < t->tw; i++) { | |
252 sp[i] = va_arg(ap, int); | |
253 } | |
254 va_end(ap); | |
255 p = t->sb; | |
256 tw = t->tw; | |
257 nb = sizeof(*t->sb)*tw; | |
258 nt = t->nt; | |
259 for (i = 0; i < nt; i++, p += tw) { | |
260 for (j = 0; j < tw; j++) { | |
261 if ((flag = sp[j] - p[j]) < 0) { | |
262 goto b; | |
263 } | |
264 if (flag > 0) { | |
265 goto c; | |
266 } | |
267 } | |
268 return 1; | |
269 c: | |
270 continue; | |
271 b: | |
272 break; | |
273 } | |
274 memmove(p+tw,p,nb*(nt - i)); | |
275 va_start(ap, t); | |
276 for (i = 0; i < t->tw; i++) { | |
277 p[i] = va_arg(ap, int); | |
278 } | |
279 t->nt++; | |
280 va_end(ap); | |
281 return 0; | |
282 } | |
283 | |
284 void at(tsd *t,...) { | |
285 va_list ap; | |
286 int *sp; | |
287 int i; | |
288 unsigned long size; | |
289 unsigned long lim; | |
290 | |
291 check_stack; | |
292 check_tsd(t); | |
293 if (t->nt >= t->na) { | |
294 if (t->na == 0) { | |
295 size = 32; | |
296 } | |
297 else if (t->na > ((MAX_BYTES/2)/3)) { | |
298 size = MAX_BYTES; | |
299 } | |
300 else { | |
301 size = 1 + t->na + t->na/2; | |
302 } | |
303 | |
304 lim = MAX_BYTES/(t->tw * sizeof(*t->sb)); | |
305 if (size > lim) { | |
306 size = lim; | |
307 } | |
308 LOGSECTION("at::resize"); | |
309 LOGV(t->nt) LCV(size); | |
310 assert(t->nt < size); | |
311 | |
312 t->sb = reallocate(t->sb, t->tw*(int)size, int); | |
313 t->na = (unsigned) size; | |
314 } | |
315 | |
316 va_start(ap,t); | |
317 sp = t->sb + t->tw * t->nt; | |
318 for (i = t->tw; i--; ) { | |
319 *sp++ = va_arg(ap, int); | |
320 } | |
321 t->nt++; | |
322 va_end(ap); | |
323 } | |
324 | |
325 void xtx(tsd *t, unsigned x, ...) { | |
326 va_list ap; | |
327 int *sp; | |
328 unsigned i; | |
329 | |
330 check_stack; | |
331 check_tsd(t); | |
332 assert(x < t->nt); | |
333 va_start(ap, x); | |
334 sp = t->sb + t->tw*x; | |
335 for (i = 0; i<t->tw; i++) { | |
336 *(va_arg(ap, int*)) = sp[i]; | |
337 } | |
338 va_end(ap); | |
339 } | |
340 | |
341 void xtxf(tsd *t, unsigned x, ...) { | |
342 va_list ap; | |
343 int *sp; | |
344 unsigned i; | |
345 | |
346 va_start(ap, x); | |
347 sp = t->sb+t->tw*x; | |
348 for (i = t->tw; i--; ) { | |
349 *(va_arg(ap, int*)) = *sp++; | |
350 } | |
351 va_end(ap); | |
352 } | |
353 |