예제 #1
0
bool InspIRCd::Match(const std::string &str, const std::string &mask, unsigned const char *map)
{
	if (!map)
		map = national_case_insensitive_map;

	return match_internal((const unsigned char *)str.c_str(), (const unsigned char *)mask.c_str(), map);
}
예제 #2
0
static void match_internal(match_context_t *context) {
    size_t j;

    for (j = 0; j < context->state->patterns.used; j++) {
        full_pcre_t *regex;
        int options = PCRE_NO_UTF8_CHECK;

        /* If the regex member == NULL, this highlight is either a pointer to
           another state which we should search here ("use"), or it is an end
           pattern with a dynamic back reference. */
        if (context->state->patterns.data[j].regex.regex == NULL) {
            if (context->state->patterns.data[j].next_state >= 0) {
                state_t *save_state;
                save_state = context->state;
                context->state = &context->match->highlight->states.data[context->state->patterns.data[j].next_state];
                match_internal(context);
                context->state = save_state;
                continue;
            }
            regex = &context->match->mapping.data[context->match->state].dynamic->regex;
        } else {
            regex = &context->state->patterns.data[j].regex;
            /* For items that do not change state, we do not want an empty match
               ever (makes no progress). */
            if (context->state->patterns.data[j].next_state == NO_CHANGE)
                options |= PCRE_NOTEMPTY;
            /* The default behaviour is to not allow start patterns to be empty, such
               that progress will be guaranteed. */
            else if (context->state->patterns.data[j].next_state > NO_CHANGE &&
                     !(context->match->highlight->flags & T3_HIGHLIGHT_ALLOW_EMPTY_START))
                options |= PCRE_NOTEMPTY;
        }

        if (pcre_exec(regex->regex, regex->extra,
                      context->line, context->size, context->match->match_start, options, context->ovector,
                      sizeof(context->ovector) / sizeof(context->ovector[0])) >= 0 && context->ovector[1] > context->best_end)
        {
            context->best = &context->state->patterns.data[j];
            context->best_end = context->ovector[1];
            if (context->best->extra != NULL && context->best->extra->dynamic_name != NULL) {
                int string_number = pcre_get_stringnumber(context->best->regex.regex, context->best->extra->dynamic_name);
                if (string_number == PCRE_ERROR_NOSUBSTRING || string_number > 10) {
                    context->extract_start = 0;
                    context->extract_end = 0;
                } else {
                    context->extract_start = context->ovector[string_number * 2];
                    context->extract_end = context->ovector[string_number * 2 + 1];
                }
            }

        }
    }

}
예제 #3
0
bool InspIRCd::Match(const char *str, const char *mask, unsigned const char *map)
{
	if (!map)
		map = national_case_insensitive_map;
	return match_internal((const unsigned char *)str, (const unsigned char *)mask, map);
}
예제 #4
0
t3_bool t3_highlight_match(t3_highlight_match_t *match, const char *line, size_t size) {
    match_context_t context;

    if ((match->highlight->flags & (T3_HIGHLIGHT_UTF8 | T3_HIGHLIGHT_UTF8_NOCHECK)) == T3_HIGHLIGHT_UTF8 && !match->utf8_checked) {
        if (!t3_highlight_utf8check(line, size)) {
            match->state = 0;
            match->begin_attribute = 0;
            match->match_attribute = 0;
            match->start = match->match_start = match->end = -1;
            return t3_false;
        }
        match->utf8_checked = t3_true;
    }

    context.match = match;
    context.line = line;
    context.size = size;
    context.state = &match->highlight->states.data[match->mapping.data[match->state].highlight_state];
    context.best = NULL;
    context.best_end = -1;

    match->start = match->end;
    match->begin_attribute = context.state->attribute_idx;

    if (match->last_progress != match->end) {
        match->last_progress = match->end;
        match->last_progress_state = match->state;
    } else if (match->last_progress_state < match->state) {
        match->last_progress_state = match->state;
    }

    for (match->match_start = match->end; match->match_start <= size; match->match_start +=
                (match->highlight->flags & T3_HIGHLIGHT_UTF8) ? step_utf8(line[match->match_start]) : 1)
    {
        match_internal(&context);

        if (context.best != NULL) {
            dst_idx_t next_state = find_state(match, context.best->next_state, context.best->extra,
                                              line + context.extract_start, context.extract_end - context.extract_start,
                                              context.best->extra != NULL ? context.best->extra->dynamic_pattern : NULL);

            /* Check if we have come full circle. If so, continue to the next byte and start over. */
            if (match->last_progress == (size_t) context.best_end &&
                    context.best->next_state > NO_CHANGE &&
                    match->last_progress_state == next_state)
            {
                context.best = NULL;
                continue;
            }

            match->end = context.best_end;
            match->state = next_state;
            if (context.best->extra != NULL && context.best->extra->on_entry != NULL) {
                int i;
                for (i = 0; i < context.best->extra->on_entry_cnt; i++) {
                    match->state = find_state(match, context.best->extra->on_entry[i].state, context.best->extra,
                                              line + context.extract_start, context.extract_end - context.extract_start,
                                              context.best->extra->on_entry[i].end_pattern);
                }
            }
            match->match_attribute = context.best->attribute_idx;
            return t3_true;
        }
    }

    match->match_start = size;
    match->end = size;
    return t3_false;
}