Пример #1
0
Файл: syntax.c Проект: artzub/mc
static struct syntax_rule
apply_rules_going_right (WEdit * edit, long i, struct syntax_rule rule)
{
    struct context_rule *r;
    int c;
    gboolean contextchanged = FALSE;
    gboolean found_left = FALSE, found_right = FALSE;
    gboolean keyword_foundleft = FALSE, keyword_foundright = FALSE;
    gboolean is_end;
    long end = 0;
    struct syntax_rule _rule = rule;

    c = xx_tolower (edit, edit_get_byte (edit, i));
    if (c == 0)
        return rule;
    is_end = (rule.end == (unsigned char) i);

    /* check to turn off a keyword */
    if (_rule.keyword)
    {
        if (edit_get_byte (edit, i - 1) == '\n')
            _rule.keyword = 0;
        if (is_end)
        {
            _rule.keyword = 0;
            keyword_foundleft = TRUE;
        }
    }

    /* check to turn off a context */
    if (_rule.context && !_rule.keyword)
    {
        long e;

        r = edit->rules[_rule.context];
        if (r->first_right == c && !(rule.border & RULE_ON_RIGHT_BORDER)
            && (e =
                compare_word_to_right (edit, i, r->right, r->whole_word_chars_left,
                                       r->whole_word_chars_right, r->line_start_right)) > 0)
        {
            _rule.end = e;
            found_right = TRUE;
            _rule.border = RULE_ON_RIGHT_BORDER;
            if (r->between_delimiters)
                _rule.context = 0;
        }
        else if (is_end && rule.border & RULE_ON_RIGHT_BORDER)
        {
            /* always turn off a context at 4 */
            found_left = TRUE;
            _rule.border = 0;
            if (!keyword_foundleft)
                _rule.context = 0;
        }
        else if (is_end && rule.border & RULE_ON_LEFT_BORDER)
        {
            /* never turn off a context at 2 */
            found_left = TRUE;
            _rule.border = 0;
        }
    }

    /* check to turn on a keyword */
    if (!_rule.keyword)
    {
        const char *p;

        r = edit->rules[_rule.context];
        p = r->keyword_first_chars;

        if (p != NULL)
            while (*(p = xx_strchr (edit, (unsigned char *) p + 1, c)) != '\0')
            {
                struct key_word *k;
                int count;
                long e;

                count = p - r->keyword_first_chars;
                k = r->keyword[count];
                e = compare_word_to_right (edit, i, k->keyword, k->whole_word_chars_left,
                                           k->whole_word_chars_right, k->line_start);
                if (e > 0)
                {
                    end = e;
                    _rule.end = e;
                    _rule.keyword = count;
                    keyword_foundright = TRUE;
                    break;
                }
            }
    }

    /* check to turn on a context */
    if (!_rule.context)
    {
        if (!found_left && is_end)
        {
            if (rule.border & RULE_ON_RIGHT_BORDER)
            {
                _rule.border = 0;
                _rule.context = 0;
                contextchanged = TRUE;
                _rule.keyword = 0;

            }
            else if (rule.border & RULE_ON_LEFT_BORDER)
            {
                r = edit->rules[_rule._context];
                _rule.border = 0;
                if (r->between_delimiters)
                {
                    _rule.context = _rule._context;
                    contextchanged = TRUE;
                    _rule.keyword = 0;

                    if (r->first_right == c)
                    {
                        long e;

                        e = compare_word_to_right (edit, i, r->right, r->whole_word_chars_left,
                                                   r->whole_word_chars_right, r->line_start_right);
                        if (e >= end)
                        {
                            _rule.end = e;
                            found_right = TRUE;
                            _rule.border = RULE_ON_RIGHT_BORDER;
                            _rule.context = 0;
                        }
                    }
                }
            }
        }

        if (!found_right)
        {
            int count;
            struct context_rule **rules = edit->rules;

            for (count = 1; rules[count]; count++)
            {
                r = rules[count];
                if (r->first_left == c)
                {
                    long e;

                    e = compare_word_to_right (edit, i, r->left, r->whole_word_chars_left,
                                               r->whole_word_chars_right, r->line_start_left);
                    if (e >= end && (!_rule.keyword || keyword_foundright))
                    {
                        _rule.end = e;
                        found_right = TRUE;
                        _rule.border = RULE_ON_LEFT_BORDER;
                        _rule._context = count;
                        if (!r->between_delimiters && !_rule.keyword)
                        {
                            _rule.context = count;
                            contextchanged = TRUE;
                        }
                        break;
                    }
                }
            }
        }
    }

    /* check again to turn on a keyword if the context switched */
    if (contextchanged && !_rule.keyword)
    {
        const char *p;

        r = edit->rules[_rule.context];
        p = r->keyword_first_chars;

        while (*(p = xx_strchr (edit, (unsigned char *) p + 1, c)) != '\0')
        {
            struct key_word *k;
            int count;
            long e;

            count = p - r->keyword_first_chars;
            k = r->keyword[count];
            e = compare_word_to_right (edit, i, k->keyword, k->whole_word_chars_left,
                                       k->whole_word_chars_right, k->line_start);
            if (e > 0)
            {
                _rule.end = e;
                _rule.keyword = count;
                break;
            }
        }
    }

    return _rule;
}
Пример #2
0
static void
apply_rules_going_right (WEdit * edit, off_t i)
{
    context_rule_t *r;
    int c;
    gboolean contextchanged = FALSE;
    gboolean found_left = FALSE, found_right = FALSE;
    gboolean keyword_foundleft = FALSE, keyword_foundright = FALSE;
    gboolean is_end;
    off_t end = 0;
    edit_syntax_rule_t _rule = edit->rule;

    c = xx_tolower (edit, edit_buffer_get_byte (&edit->buffer, i));
    if (c == 0)
        return;

    is_end = (edit->rule.end == i);

    /* check to turn off a keyword */
    if (_rule.keyword != 0)
    {
        if (edit_buffer_get_byte (&edit->buffer, i - 1) == '\n')
            _rule.keyword = 0;
        if (is_end)
        {
            _rule.keyword = 0;
            keyword_foundleft = TRUE;
        }
    }

    /* check to turn off a context */
    if (_rule.context != 0 && _rule.keyword == 0)
    {
        off_t e;

        r = CONTEXT_RULE (g_ptr_array_index (edit->rules, _rule.context));
        if (r->first_right == c && (edit->rule.border & RULE_ON_RIGHT_BORDER) == 0
            && (e =
                compare_word_to_right (edit, i, r->right, r->whole_word_chars_left,
                                       r->whole_word_chars_right, r->line_start_right)) > 0)
        {
            _rule.end = e;
            found_right = TRUE;
            _rule.border = RULE_ON_RIGHT_BORDER;
            if (r->between_delimiters)
                _rule.context = 0;
        }
        else if (is_end && (edit->rule.border & RULE_ON_RIGHT_BORDER) != 0)
        {
            /* always turn off a context at 4 */
            found_left = TRUE;
            _rule.border = 0;
            if (!keyword_foundleft)
                _rule.context = 0;
        }
        else if (is_end && (edit->rule.border & RULE_ON_LEFT_BORDER) != 0)
        {
            /* never turn off a context at 2 */
            found_left = TRUE;
            _rule.border = 0;
        }
    }

    /* check to turn on a keyword */
    if (_rule.keyword == 0)
    {
        const char *p;

        r = CONTEXT_RULE (g_ptr_array_index (edit->rules, _rule.context));
        p = r->keyword_first_chars;

        if (p != NULL)
            while (*(p = xx_strchr (edit, (const unsigned char *) p + 1, c)) != '\0')
            {
                syntax_keyword_t *k;
                int count;
                off_t e;

                count = p - r->keyword_first_chars;
                k = SYNTAX_KEYWORD (g_ptr_array_index (r->keyword, count));
                e = compare_word_to_right (edit, i, k->keyword, k->whole_word_chars_left,
                                           k->whole_word_chars_right, k->line_start);
                if (e > 0)
                {
                    /* when both context and keyword terminate with a newline,
                       the context overflows to the next line and colorizes it incorrectly */
                    if (e > i + 1 && _rule._context != 0
                        && k->keyword[strlen (k->keyword) - 1] == '\n')
                    {
                        r = CONTEXT_RULE (g_ptr_array_index (edit->rules, _rule._context));
                        if (r->right != NULL && r->right[0] != '\0'
                            && r->right[strlen (r->right) - 1] == '\n')
                            e--;
                    }

                    end = e;
                    _rule.end = e;
                    _rule.keyword = count;
                    keyword_foundright = TRUE;
                    break;
                }
            }
    }

    /* check to turn on a context */
    if (_rule.context == 0)
    {
        if (!found_left && is_end)
        {
            if ((edit->rule.border & RULE_ON_RIGHT_BORDER) != 0)
            {
                _rule.border = 0;
                _rule.context = 0;
                contextchanged = TRUE;
                _rule.keyword = 0;

            }
            else if ((edit->rule.border & RULE_ON_LEFT_BORDER) != 0)
            {
                r = CONTEXT_RULE (g_ptr_array_index (edit->rules, _rule._context));
                _rule.border = 0;
                if (r->between_delimiters)
                {
                    _rule.context = _rule._context;
                    contextchanged = TRUE;
                    _rule.keyword = 0;

                    if (r->first_right == c)
                    {
                        off_t e;

                        e = compare_word_to_right (edit, i, r->right, r->whole_word_chars_left,
                                                   r->whole_word_chars_right, r->line_start_right);
                        if (e >= end)
                        {
                            _rule.end = e;
                            found_right = TRUE;
                            _rule.border = RULE_ON_RIGHT_BORDER;
                            _rule.context = 0;
                        }
                    }
                }
            }
        }

        if (!found_right)
        {
            size_t count;

            for (count = 1; count < edit->rules->len; count++)
            {
                r = CONTEXT_RULE (g_ptr_array_index (edit->rules, count));
                if (r->first_left == c)
                {
                    off_t e;

                    e = compare_word_to_right (edit, i, r->left, r->whole_word_chars_left,
                                               r->whole_word_chars_right, r->line_start_left);
                    if (e >= end && (_rule.keyword == 0 || keyword_foundright))
                    {
                        _rule.end = e;
                        found_right = TRUE;
                        _rule.border = RULE_ON_LEFT_BORDER;
                        _rule._context = count;
                        if (!r->between_delimiters && _rule.keyword == 0)
                        {
                            _rule.context = count;
                            contextchanged = TRUE;
                        }
                        break;
                    }
                }
            }
        }
    }

    /* check again to turn on a keyword if the context switched */
    if (contextchanged && _rule.keyword == 0)
    {
        const char *p;

        r = CONTEXT_RULE (g_ptr_array_index (edit->rules, _rule.context));
        p = r->keyword_first_chars;

        while (*(p = xx_strchr (edit, (const unsigned char *) p + 1, c)) != '\0')
        {
            syntax_keyword_t *k;
            int count;
            off_t e;

            count = p - r->keyword_first_chars;
            k = SYNTAX_KEYWORD (g_ptr_array_index (r->keyword, count));
            e = compare_word_to_right (edit, i, k->keyword, k->whole_word_chars_left,
                                       k->whole_word_chars_right, k->line_start);
            if (e > 0)
            {
                _rule.end = e;
                _rule.keyword = count;
                break;
            }
        }
    }

    edit->rule = _rule;
}