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; }
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; }