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 rlong rpa_record_getruleuid(rarray_t *records, rlong rec)
271 rec = rpa_recordtree_get(records, rec, RPA_RECORD_START);
272 if (rec >= r_array_length(records))
274 prec = (rparecord_t *)r_array_slot(records, rec);
275 return prec->ruleuid;
279 void rpa_record_setusertype(rarray_t *records, rlong rec, ruint32 usertype, rvalset_t op)
285 rec = rpa_recordtree_get(records, rec, RPA_RECORD_START);
286 if (rec >= r_array_length(records))
288 prec = (rparecord_t *)r_array_slot(records, rec);
289 rpa_recordptr_setusertype(prec, usertype, op);
290 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
291 if (rec >= r_array_length(records))
293 prec = (rparecord_t *)r_array_slot(records, rec);
294 rpa_recordptr_setusertype(prec, usertype, op);
298 rlong rpa_record_getusertype(rarray_t *records, rlong rec)
304 rec = rpa_recordtree_get(records, rec, RPA_RECORD_START);
305 if (rec >= r_array_length(records))
307 prec = (rparecord_t *)r_array_slot(records, rec);
308 return prec->usertype;
312 rint rpa_record_optchar(rparecord_t *prec, rint defc)
316 if ((prec->usertype & RPA_MATCH_MASK) == RPA_MATCH_OPTIONAL)
318 else if ((prec->usertype & RPA_MATCH_MASK) == RPA_MATCH_MULTIPLE)
320 else if ((prec->usertype & RPA_MATCH_MASK) == RPA_MATCH_MULTIOPT)
328 rint rpa_record_loopchar(rparecord_t *prec, rint defc)
332 if ((prec->usertype & RPA_LOOP_PATH) && (prec->usertype & RPA_NONLOOP_PATH)) {
334 * This is an error, should never happen
337 } else if ((prec->usertype & RPA_LOOP_PATH)) {
339 } else if ((prec->usertype & RPA_NONLOOP_PATH)) {
348 void rpa_record_dump(rarray_t *records, rlong rec)
351 rlong start, end, first, last, next, prev, parent;
353 rint bufsize = sizeof(buf) - 1;
357 if (rec < 0 || rec >= r_array_length(records))
359 prec = (rparecord_t *)r_array_slot(records, rec);
360 if (prec->type & RPA_RECORD_END) {
361 if ((prec->usertype & RPA_MATCH_MASK) == RPA_MATCH_OPTIONAL)
363 else if ((prec->usertype & RPA_MATCH_MASK) == RPA_MATCH_MULTIPLE)
365 else if ((prec->usertype & RPA_MATCH_MASK) == RPA_MATCH_MULTIOPT)
369 r_memset(buf, 0, bufsize);
371 start = rpa_recordtree_get(records, rec, RPA_RECORD_START);
372 end = rpa_recordtree_get(records, rec, RPA_RECORD_END);
373 first = rpa_recordtree_firstchild(records, rec, RPA_RECORD_START);
374 last = rpa_recordtree_lastchild(records, rec, RPA_RECORD_START);
375 next = rpa_recordtree_next(records, rec, RPA_RECORD_START);
376 prev = rpa_recordtree_prev(records, rec, RPA_RECORD_START);
377 parent = rpa_recordtree_parent(records, rec, RPA_RECORD_START);
379 // n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, "%5d ( %7ld, %4d ) : ", rec, prec->ruleid, (ruint32)prec->ruleuid);
380 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);
381 if (prec->type & RPA_RECORD_START)
382 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, "START ");
383 if (prec->type & RPA_RECORD_END)
384 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, "END ");
385 if (prec->type & RPA_RECORD_HEAD)
386 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, "HEAD ");
387 if (prec->type & RPA_RECORD_TAIL)
388 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, "TAIL ");
389 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, "%s ", prec->rule);
391 r_memset(buf + n, ' ', bufsize - n);
393 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, " %5d, %3d", prec->top, prec->size);
395 r_memset(buf + n, ' ', bufsize - n);
397 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, " %c %c %c", optc,
398 (prec->usertype & RPA_LOOP_PATH) ? 'L' : ' ', (prec->usertype & RPA_NONLOOP_PATH) ? 'N' : ' ');
399 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, " : ");
400 size = prec->inputsiz;
401 if (size >= bufsize - n - 1)
402 size = bufsize - n - 1;
403 if (prec->type & RPA_RECORD_END) {
404 r_strncpy(buf + n, prec->input, size);
409 r_printf("%s\n", buf);
413 void rpa_record_dumpindented(rarray_t *records, rlong rec, rint level)
419 if (rec < 0 || rec >= r_array_length(records))
421 r_memset(buffer, 0, sizeof(buffer));
422 prec = (rparecord_t *)r_array_slot(records, rec);
423 for (i = 0; i < level; i++)
427 r_printf("%s, %c, %c", prec->rule, rpa_record_optchar(prec, 'x'), rpa_record_loopchar(prec, 'x'));
429 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
430 prec = (rparecord_t *)r_array_slot(records, rec);
431 size = R_MIN(prec->inputsiz, sizeof(buffer) - 1);
432 r_strncpy(buffer, prec->input, size);
434 if (size == (sizeof(buffer) - 1))
435 r_printf(" %s ...\n", buffer);
437 r_printf(" %s\n", buffer);