Parse relationship: -[:TYPE|TYPE2*min..max]-> or <-[...]- */
| 703 | |
| 704 | /* Parse relationship: -[:TYPE|TYPE2*min..max]-> or <-[...]- */ |
| 705 | static int parse_rel(parser_t *p, cbm_rel_pattern_t *out) { |
| 706 | memset(out, 0, sizeof(*out)); |
| 707 | out->min_hops = SKIP_ONE; |
| 708 | out->max_hops = SKIP_ONE; |
| 709 | |
| 710 | /* Check for leading < (inbound) */ |
| 711 | bool leading_lt = match(p, TOK_LT); |
| 712 | if (!expect(p, TOK_DASH)) { |
| 713 | return CBM_NOT_FOUND; |
| 714 | } |
| 715 | |
| 716 | /* Optional bracket content */ |
| 717 | if (match(p, TOK_LBRACKET)) { |
| 718 | if (parse_rel_bracket(p, out) < 0) { |
| 719 | return CBM_NOT_FOUND; |
| 720 | } |
| 721 | } |
| 722 | |
| 723 | if (!expect(p, TOK_DASH)) { |
| 724 | return CBM_NOT_FOUND; |
| 725 | } |
| 726 | |
| 727 | /* Check for trailing > (outbound) */ |
| 728 | bool trailing_gt = match(p, TOK_GT); |
| 729 | |
| 730 | /* Determine direction */ |
| 731 | if (leading_lt && !trailing_gt) { |
| 732 | out->direction = heap_strdup("inbound"); |
| 733 | } else if (!leading_lt && trailing_gt) { |
| 734 | out->direction = heap_strdup("outbound"); |
| 735 | } else { |
| 736 | out->direction = heap_strdup("any"); |
| 737 | } |
| 738 | |
| 739 | return 0; |
| 740 | } |
| 741 | |
| 742 | /* ── Expression tree helpers ────────────────────────────────────── */ |
| 743 |
no test coverage detected