hale_internal b32 _scope_path_match(ScopePath *path, ScopeSelector *selector, ScopeSelectorMatch *match) { // TODO: Case with empty selector. // TODO: Also when both path and selector are empty, it's a match. if (selector->empty() || path->nodes.count == 0) { return 0; } // TODO: Walk backwards, so we fail sooner. u32 s; ScopeSelectorSequence *sequence = selector->sequence(); ScopeSelectorElement *element_it = sequence->elements_begin(); ScopeSelectorElement *element_end = sequence->elements_end(); ScopeNode *path_it = path->nodes.ptr; ScopeNode *path_end = path_it + path->nodes.count; while (path_it != path_end && element_it != element_end) { if (s = _match_names(element_it->name()->ids_begin(), element_it->name()->ids_end(), path_it->names, path_it->names + path_it->names_count)) { match_plus(match, path_it - path->nodes.ptr, s); path_it++; } element_it = element_it->next(); } return element_it == element_end; }
static bool match_here(struct utf8_iter expr, struct utf8_iter text, char **end) { unsigned pre = expr.chr; int flags = 0; if (pre == 0) { if (end != NULL) *end = text.head; return true; } if (pre == '~') { pre = utf8_next(&expr); flags |= NEGATE; } if (pre == '%') { pre = utf8_next(&expr); switch (pre) { case 'a': /* alpha */ case 'd': /* digit */ case 'f': /* float */ case 'g': /* graphic */ case 'n': /* newline */ case 's': /* space */ case 'x': /* hex */ case '?': /* anything */ flags |= CLASS; } } utf8_next(&expr); if (expr.chr == '*') { utf8_next(&expr); return match_star(pre, flags, expr, text, end); } else if (expr.chr == '+') { utf8_next(&expr); return match_plus(pre, flags, expr, text, end); } if (pre == '$' && expr.chr == 0) { if (end != NULL) *end = text.head; return text.chr == 0; } if (text.chr != 0 && match_char(pre, flags, &text)) { utf8_next(&text); return match_here(expr, text, end); } return false; }