7 rparecord_t *rpa_record_get(rarray_t *records, rlong rec)
13 if (rec < 0 || rec >= r_array_length(records))
15 prec = (rparecord_t *)r_array_slot(records, rec);
21 rlong rpa_recordtree_get(rarray_t *records, rlong rec, rulong type)
24 ruint startrec = (type & RPA_RECORD_START) ? 1 : 0;
27 if (rec < 0 || rec >= r_array_length(records))
29 prec = (rparecord_t *)r_array_slot(records, rec);
30 if ((prec->type & RPA_RECORD_START)) {
33 for (s = 0, i = rec; i < r_array_length(records); i++) {
34 prec = (rparecord_t *)r_array_slot(records, i);
35 if (prec->type & RPA_RECORD_START)
37 if (prec->type & RPA_RECORD_END)
43 prec = (rparecord_t *)r_array_slot(records, rec);
44 if ((prec->type & RPA_RECORD_END)) {
47 for (s = 0, i = rec; i >= 0; i--) {
48 prec = (rparecord_t *)r_array_slot(records, i);
49 if (prec->type & RPA_RECORD_START)
51 if (prec->type & RPA_RECORD_END)
62 rlong rpa_recordtree_firstchild(rarray_t *records, rlong rec, rulong type)
66 if (rec < 0 || rec >= r_array_length(records))
68 prec = (rparecord_t *)r_array_slot(records, rec);
69 if (prec->type & RPA_RECORD_END) {
70 if ((rec = rpa_recordtree_get(records, rec, RPA_RECORD_START)) < 0)
73 if (++rec >= r_array_length(records))
75 prec = (rparecord_t *)r_array_slot(records, rec);
76 if (prec->type & RPA_RECORD_START)
77 return rpa_recordtree_get(records, rec, type);
82 rlong rpa_recordtree_lastchild(rarray_t *records, rlong rec, rulong type)
86 if (rec < 0 || rec >= r_array_length(records))
88 prec = (rparecord_t *)r_array_slot(records, rec);
89 if (prec->type & RPA_RECORD_START) {
90 if ((rec = rpa_recordtree_get(records, rec, RPA_RECORD_END)) < 0)
95 prec = (rparecord_t *)r_array_slot(records, rec);
96 if (prec->type & RPA_RECORD_END)
97 return rpa_recordtree_get(records, rec, type);
102 rlong rpa_recordtree_next(rarray_t *records, rlong rec, rulong type)
106 if (rec < 0 || rec >= r_array_length(records))
108 prec = (rparecord_t *)r_array_slot(records, rec);
109 if (prec->type & RPA_RECORD_START) {
110 if ((rec = rpa_recordtree_get(records, rec, RPA_RECORD_END)) < 0)
113 if (++rec >= r_array_length(records))
115 prec = (rparecord_t *)r_array_slot(records, rec);
116 if (prec->type & RPA_RECORD_START)
117 return rpa_recordtree_get(records, rec, type);
122 rlong rpa_recordtree_prev(rarray_t *records, rlong rec, rulong type)
126 if (rec < 0 || rec >= r_array_length(records))
128 prec = (rparecord_t *)r_array_slot(records, rec);
129 if (prec->type & RPA_RECORD_END) {
130 if ((rec = rpa_recordtree_get(records, rec, RPA_RECORD_START)) < 0)
135 prec = (rparecord_t *)r_array_slot(records, rec);
136 if (prec->type & RPA_RECORD_END)
137 return rpa_recordtree_get(records, rec, type);
142 rlong rpa_recordtree_parent(rarray_t *records, rlong rec, rulong type)
144 rlong last = -1, parent = -1;
146 if (rec < 0 || rec >= r_array_length(records))
148 for ( ;rec >= 0; rec = rpa_recordtree_next(records, last, RPA_RECORD_END)) {
149 last = rpa_recordtree_get(records, rec, RPA_RECORD_END);
152 if (parent >= r_array_length(records))
154 return rpa_recordtree_get(records, parent, type);
158 rlong rpa_recordtree_size(rarray_t *records, rlong rec)
160 rlong first = rpa_recordtree_get(records, rec, RPA_RECORD_START);
161 rlong last = rpa_recordtree_get(records, rec, RPA_RECORD_END);
162 if (first < 0 || last < 0)
164 return (last - first + 1);
168 rlong rpa_recordtree_rotatedown(rarray_t *records, rlong parent)
171 rlong nallrecs = r_array_length(records);
172 rlong firstchild = rpa_recordtree_firstchild(records, parent, RPA_RECORD_START);
173 rlong lastchild = rpa_recordtree_lastchild(records, parent, RPA_RECORD_START);
176 if (firstchild < 0 || lastchild == firstchild)
179 * Copy the last child at the end
181 nlastchild = rpa_recordtree_size(records, lastchild);
182 r_array_move(records, nallrecs, lastchild, nlastchild);
185 * Push down all children, but the last one (overwriting the last one)
187 copysiz = lastchild - firstchild;
188 r_array_move(records, firstchild + nlastchild, firstchild, copysiz);
191 * Copy the last child to become the first one
193 r_array_move(records, firstchild, nallrecs, nlastchild);
196 * Restore the original size
198 r_array_setlength(records, nallrecs);
203 rlong rpa_recordtree_rotateup(rarray_t *records, rlong parent)
212 rlong rpa_recordtree_copy(rarray_t *dst, rarray_t *src, rlong rec)
216 rec = rpa_recordtree_get(src, rec, RPA_RECORD_START);
217 size = rpa_recordtree_size(src, rec);
219 for (i = 0; i < size; i++) {
220 prec = rpa_record_get(src, i);
221 r_array_add(dst, prec);
227 rlong rpa_recordtree_walk(rarray_t *records, rlong rec, rlong level, rpa_recordtree_callback callback, rpointer userdata)
233 rec = rpa_recordtree_get(records, rec, RPA_RECORD_START);
234 if (callback && callback(records, rec, userdata) < 0)
236 for (child = rpa_recordtree_firstchild(records, rec, RPA_RECORD_START); child >= 0; child = rpa_recordtree_next(records, child, RPA_RECORD_START)) {
237 if (rpa_recordtree_walk(records, child, level + 1, callback, userdata) < 0)
240 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
241 if (callback && callback(records, rec, userdata) < 0)
247 static void rpa_recordptr_setusertype(rparecord_t *prec, ruint32 usertype, rvalset_t op)
251 prec->usertype |= usertype;
254 prec->usertype ^= usertype;
257 prec->usertype &= usertype;
260 prec->usertype = usertype;
265 void rpa_record_setusertype(rarray_t *records, rlong rec, ruint32 usertype, rvalset_t op)
269 rec = rpa_recordtree_get(records, rec, RPA_RECORD_START);
270 if (rec >= r_array_length(records))
272 prec = (rparecord_t *)r_array_slot(records, rec);
273 rpa_recordptr_setusertype(prec, usertype, op);
274 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
275 if (rec >= r_array_length(records))
277 prec = (rparecord_t *)r_array_slot(records, rec);
278 rpa_recordptr_setusertype(prec, usertype, op);
282 rlong rpa_record_getusertype(rarray_t *records, rlong rec)
286 rec = rpa_recordtree_get(records, rec, RPA_RECORD_START);
287 if (rec >= r_array_length(records))
289 prec = (rparecord_t *)r_array_slot(records, rec);
290 return prec->usertype;
294 rint rpa_record_optchar(rparecord_t *prec, rint defc)
298 if ((prec->usertype & RPA_MATCH_MASK) == RPA_MATCH_OPTIONAL)
300 else if ((prec->usertype & RPA_MATCH_MASK) == RPA_MATCH_MULTIPLE)
302 else if ((prec->usertype & RPA_MATCH_MASK) == RPA_MATCH_MULTIOPT)
310 rint rpa_record_loopchar(rparecord_t *prec, rint defc)
314 if ((prec->usertype & RPA_LOOP_PATH) && (prec->usertype & RPA_NONLOOP_PATH)) {
316 * This is an error, should never happen
319 } else if ((prec->usertype & RPA_LOOP_PATH)) {
321 } else if ((prec->usertype & RPA_NONLOOP_PATH)) {
330 void rpa_record_dump(rarray_t *records, rlong rec)
333 rlong start, end, first, last, next, prev, parent;
335 rint bufsize = sizeof(buf) - 1;
339 if (rec < 0 || rec >= r_array_length(records))
341 prec = (rparecord_t *)r_array_slot(records, rec);
342 if (prec->type & RPA_RECORD_END) {
343 if ((prec->usertype & RPA_MATCH_MASK) == RPA_MATCH_OPTIONAL)
345 else if ((prec->usertype & RPA_MATCH_MASK) == RPA_MATCH_MULTIPLE)
347 else if ((prec->usertype & RPA_MATCH_MASK) == RPA_MATCH_MULTIOPT)
351 r_memset(buf, 0, bufsize);
353 start = rpa_recordtree_get(records, rec, RPA_RECORD_START);
354 end = rpa_recordtree_get(records, rec, RPA_RECORD_END);
355 first = rpa_recordtree_firstchild(records, rec, RPA_RECORD_START);
356 last = rpa_recordtree_lastchild(records, rec, RPA_RECORD_START);
357 next = rpa_recordtree_next(records, rec, RPA_RECORD_START);
358 prev = rpa_recordtree_prev(records, rec, RPA_RECORD_START);
359 parent = rpa_recordtree_parent(records, rec, RPA_RECORD_START);
361 // n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, "%5d ( %7ld, %4d ) : ", rec, prec->ruleid, (ruint32)prec->ruleuid);
362 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, "%5ld, n:%5ld (s: %5ld, e: %5ld, p: %5ld) ( %4d, 0x%03x ) : ", rec, prec->next, start, end, parent, prec->ruleuid, prec->usertype);
363 if (prec->type & RPA_RECORD_START)
364 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, "START ");
365 if (prec->type & RPA_RECORD_END)
366 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, "END ");
367 if (prec->type & RPA_RECORD_HEAD)
368 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, "HEAD ");
369 if (prec->type & RPA_RECORD_TAIL)
370 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, "TAIL ");
371 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, "%s ", prec->rule);
373 r_memset(buf + n, ' ', bufsize - n);
375 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, " %5d, %3d", prec->top, prec->size);
377 r_memset(buf + n, ' ', bufsize - n);
379 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, " %c %c %c", optc,
380 (prec->usertype & RPA_LOOP_PATH) ? 'L' : ' ', (prec->usertype & RPA_NONLOOP_PATH) ? 'N' : ' ');
381 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, " : ");
382 size = prec->inputsiz;
383 if (size >= bufsize - n - 1)
384 size = bufsize - n - 1;
385 if (prec->type & RPA_RECORD_END) {
386 r_strncpy(buf + n, prec->input, size);
391 r_printf("%s\n", buf);
395 void rpa_record_dumpindented(rarray_t *records, rlong rec, rint level)
401 if (rec < 0 || rec >= r_array_length(records))
403 r_memset(buffer, 0, sizeof(buffer));
404 prec = (rparecord_t *)r_array_slot(records, rec);
405 for (i = 0; i < level; i++)
409 r_printf("%s, %c, %c", prec->rule, rpa_record_optchar(prec, 'x'), rpa_record_loopchar(prec, 'x'));
411 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
412 prec = (rparecord_t *)r_array_slot(records, rec);
413 size = R_MIN(prec->inputsiz, sizeof(buffer) - 1);
414 r_strncpy(buffer, prec->input, size);
416 if (size == (sizeof(buffer) - 1))
417 r_printf(" %s ...\n", buffer);
419 r_printf(" %s\n", buffer);