Parse relationship: -[:TYPE|TYPE2*min..max]-> or <-[...]- */
| 729 | |
| 730 | /* Parse relationship: -[:TYPE|TYPE2*min..max]-> or <-[...]- */ |
| 731 | static int parse_rel(parser_t *p, cbm_rel_pattern_t *out) { |
| 732 | memset(out, 0, sizeof(*out)); |
| 733 | out->min_hops = SKIP_ONE; |
| 734 | out->max_hops = SKIP_ONE; |
| 735 | |
| 736 | /* Check for leading < (inbound) */ |
| 737 | bool leading_lt = match(p, TOK_LT); |
| 738 | if (!expect(p, TOK_DASH)) { |
| 739 | return CBM_NOT_FOUND; |
| 740 | } |
| 741 | |
| 742 | /* Optional bracket content */ |
| 743 | if (match(p, TOK_LBRACKET)) { |
| 744 | if (parse_rel_bracket(p, out) < 0) { |
| 745 | return CBM_NOT_FOUND; |
| 746 | } |
| 747 | } |
| 748 | |
| 749 | if (!expect(p, TOK_DASH)) { |
| 750 | return CBM_NOT_FOUND; |
| 751 | } |
| 752 | |
| 753 | /* Check for trailing > (outbound) */ |
| 754 | bool trailing_gt = match(p, TOK_GT); |
| 755 | |
| 756 | /* Determine direction */ |
| 757 | if (leading_lt && !trailing_gt) { |
| 758 | out->direction = heap_strdup("inbound"); |
| 759 | } else if (!leading_lt && trailing_gt) { |
| 760 | out->direction = heap_strdup("outbound"); |
| 761 | } else { |
| 762 | out->direction = heap_strdup("any"); |
| 763 | } |
| 764 | |
| 765 | return 0; |
| 766 | } |
| 767 | |
| 768 | /* ── Expression tree helpers ────────────────────────────────────── */ |
| 769 |
no test coverage detected