qemacs-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemacs-commit] qemacs clang.c htmlsrc.c list.c orgmode.c qe.h ...


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs clang.c htmlsrc.c list.c orgmode.c qe.h ...
Date: Sat, 05 Apr 2014 15:49:16 +0000

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        14/04/05 15:49:16

Modified files:
        .              : clang.c htmlsrc.c list.c orgmode.c qe.h dired.c 
                         latex-mode.c makemode.c perl.c script.c 
                         extra-modes.c lisp.c markdown.c qe.c xml.c 

Log message:
        pass QEColorizeContext to ColorizeFunc callbacks
        
        * pass state and state_only as members of QEColorizeContext
        * simplify ColorizeFunc, make them more consistent
        * use offsets instead of pointers to prepare for further API changes

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/clang.c?cvsroot=qemacs&r1=1.53&r2=1.54
http://cvs.savannah.gnu.org/viewcvs/qemacs/htmlsrc.c?cvsroot=qemacs&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/qemacs/list.c?cvsroot=qemacs&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/qemacs/orgmode.c?cvsroot=qemacs&r1=1.18&r2=1.19
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.h?cvsroot=qemacs&r1=1.160&r2=1.161
http://cvs.savannah.gnu.org/viewcvs/qemacs/dired.c?cvsroot=qemacs&r1=1.43&r2=1.44
http://cvs.savannah.gnu.org/viewcvs/qemacs/latex-mode.c?cvsroot=qemacs&r1=1.45&r2=1.46
http://cvs.savannah.gnu.org/viewcvs/qemacs/makemode.c?cvsroot=qemacs&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/qemacs/perl.c?cvsroot=qemacs&r1=1.16&r2=1.17
http://cvs.savannah.gnu.org/viewcvs/qemacs/script.c?cvsroot=qemacs&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/qemacs/extra-modes.c?cvsroot=qemacs&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/qemacs/lisp.c?cvsroot=qemacs&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/qemacs/markdown.c?cvsroot=qemacs&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.c?cvsroot=qemacs&r1=1.163&r2=1.164
http://cvs.savannah.gnu.org/viewcvs/qemacs/xml.c?cvsroot=qemacs&r1=1.17&r2=1.18

Patches:
Index: clang.c
===================================================================
RCS file: /sources/qemacs/qemacs/clang.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -b -r1.53 -r1.54
--- clang.c     2 Apr 2014 13:05:42 -0000       1.53
+++ clang.c     5 Apr 2014 15:49:14 -0000       1.54
@@ -123,23 +123,21 @@
     IN_C_CHARCLASS  = 0x40   /* regex char class */,
 };
 
-void c_colorize_line(unsigned int *str, int n, int mode_flags,
-                     int *colorize_state_ptr, __unused__ int state_only)
+void c_colorize_line(QEColorizeContext *cp,
+                     unsigned int *str, int n, int mode_flags)
 {
-    int i = 0, j = i, indent, c, state, style, style1, type_decl, klen, delim;
-    unsigned int *p, *p_start, *p_end, *p1, *p2;
+    int i = 0, start, i1, i2, indent;
+    int c, state, style, style1, type_decl, klen, delim;
     char kbuf[32];
 
     for (indent = 0; qe_isspace(str[indent]); indent++)
         continue;
 
-    state = *colorize_state_ptr;
-    p = str;
-    p_start = p;
-    p_end = p + n;
+    state = cp->colorize_state;
+    start = i;
     type_decl = 0;
 
-    if (p >= p_end)
+    if (i >= n)
         goto the_end;
 
     c = 0;      /* turn off stupid egcs-2.91.66 warning */
@@ -161,53 +159,49 @@
             goto parse_regex;
     }
 
-    while (p < p_end) {
-        p_start = p;
-        c = *p++;
+    while (i < n) {
+        start = i;
+        c = str[i++];
 
         switch (c) {
         case '/':
-            if (*p == '*') {
+            if (str[i] == '*') {
                 /* normal comment */
-                p++;
+                i++;
             parse_comment:
                 state |= IN_C_COMMENT;
-                while (p < p_end) {
-                    if (p[0] == '*' && p[1] == '/') {
-                        p += 2;
+                for (; i < n; i++) {
+                    if (str[i] == '*' && str[i + 1] == '/') {
+                        i += 2;
                         state &= ~IN_C_COMMENT;
                         break;
-                    } else {
-                        p++;
                     }
                 }
-                set_color(p_start, p, C_STYLE_COMMENT);
+                SET_COLOR(str, start, i, C_STYLE_COMMENT);
                 continue;
             } else
-            if (*p == '/') {
+            if (str[i] == '/') {
                 /* line comment */
             parse_comment1:
                 state |= IN_C_COMMENT1;
-                p = p_end;
-                set_color(p_start, p, C_STYLE_COMMENT);
-                goto the_end;
+                i = n;
+                SET_COLOR(str, start, i, C_STYLE_COMMENT);
+                continue;
             }
             /* XXX: should use more context to tell regex from divide */
-            i = p - str - 1;
             if ((mode_flags & CLANG_REGEX)
-            &&  (i == indent
-            ||   (str[i + 1] != ' ' && str[i + 1] != '='
-            &&    !qe_isalnum(str[i - 1] & CHAR_MASK)
-            &&    str[i - 1] != ')'))) {
+            &&  (start == indent
+            ||   (str[i] != ' ' && str[i] != '='
+            &&    !qe_isalnum(str[start - 1] & CHAR_MASK)
+            &&    str[start - 1] != ')'))) {
                 /* parse regex */
-                j = i + 1;
                 state = IN_C_REGEX;
             parse_regex:
-                while (j < n) {
-                    c = str[j++];
+                while (i < n) {
+                    c = str[i++];
                     if (c == '\\') {
-                        if (j < n) {
-                            j += 1;
+                        if (i < n) {
+                            i += 1;
                         }
                     } else
                     if (state & IN_C_CHARCLASS) {
@@ -220,17 +214,15 @@
                             state |= IN_C_CHARCLASS;
                         } else
                         if (c == '/') {
-                            while (qe_isalnum_(str[j])) {
-                                j++;
+                            while (qe_isalnum_(str[i])) {
+                                i++;
                             }
                             state = 0;
                             break;
                         }
                     }
                 }
-                SET_COLOR(str, i, j, C_STYLE_REGEX);
-                i = j;
-                p = str + i;
+                SET_COLOR(str, start, i, C_STYLE_REGEX);
                 continue;
             }
             break;
@@ -241,12 +233,12 @@
             break;
         case 'L':       /* wide character and string literals */
             /* XXX: C only */
-            if (*p == '\'') {
-                p++;
+            if (str[i] == '\'') {
+                i++;
                 goto parse_string_q;
             }
-            if (*p == '\"') {
-                p++;
+            if (str[i] == '\"') {
+                i++;
                 goto parse_string;
             }
             goto normal;
@@ -262,24 +254,21 @@
             style1 = C_STYLE_STRING;
             delim = '\"';
         string:
-            while (p < p_end) {
-                if (*p == '\\') {
-                    p++;
-                    if (p >= p_end)
+            while (i < n) {
+                c = str[i++];
+                if (c == '\\') {
+                    if (i >= n)
                         break;
-                    p++;
+                    i++;
                 } else
-                if ((int)*p == delim) {
-                    p++;
+                if (c == delim) {
                     state &= ~(IN_C_STRING | IN_C_STRING_Q);
                     break;
-                } else {
-                    p++;
                 }
             }
             if (state & IN_C_PREPROCESS)
                 style1 = C_STYLE_PREPROCESS;
-            set_color(p_start, p, style1);
+            SET_COLOR(str, start, i, style1);
             continue;
         case '=':
             /* exit type declaration */
@@ -288,7 +277,7 @@
             break;
         case '<':       /* JavaScript extension */
             /* XXX: js only */
-            if (*p == '!' && p[1] == '-' && p[2] == '-')
+            if (str[i] == '!' && str[i + 1] == '-' && str[i + 2] == '-')
                 goto parse_comment1;
             break;
         default:
@@ -296,74 +285,73 @@
             if (state & IN_C_PREPROCESS)
                 break;
             if (qe_isdigit(c)) {
-                while (qe_isalnum(*p) || *p == '.') {
-                    p++;
+                while (qe_isalnum(str[i]) || str[i] == '.') {
+                    i++;
                 }
-                set_color(p_start, p, C_STYLE_NUMBER);
+                SET_COLOR(str, start, i, C_STYLE_NUMBER);
                 continue;
             }
             if (qe_isalpha_(c)) {
                 /* XXX: should support :: and $ */
-                klen = get_c_identifier(kbuf, countof(kbuf), p - 1);
-                p += klen - 1;
+                klen = get_c_identifier(kbuf, countof(kbuf), str + start);
+                i = start + klen;
 
                 if (((mode_flags & (CLANG_C|CLANG_CPP|CLANG_OBJC)) && 
strfind(c_keywords, kbuf))
                 ||  ((mode_flags & CLANG_CPP) && strfind(cc_keywords, kbuf))
                 ||  ((mode_flags & CLANG_JS) && strfind(js_keywords, kbuf))
                 ||  ((mode_flags & CLANG_JAVA) && strfind(java_keywords, kbuf))
                    ) {
-                    set_color(p_start, p, C_STYLE_KEYWORD);
+                    SET_COLOR(str, start, i, C_STYLE_KEYWORD);
                     continue;
                 }
 
-                p1 = p;
-                while (qe_isblank(*p1))
-                    p1++;
-                p2 = p1;
-                while (*p2 == '*' || qe_isblank(*p2))
-                    p2++;
+                i1 = i;
+                while (qe_isblank(str[i1]))
+                    i1++;
+                i2 = i1;
+                while (str[i2] == '*' || qe_isblank(str[i2]))
+                    i2++;
 
                 /* XXX: should check type depending on flavor */
-                if (strfind(c_mode_types, kbuf)
-                ||  (klen > 2 && kbuf[klen - 2] == '_' && kbuf[klen - 1] == 
't')) {
+                if (strfind(c_mode_types, kbuf) || strend(kbuf, "_t", NULL)) {
                     /* c type */
                     /* if not cast, assume type declaration */
-                    if (*p2 != ')') {
+                    if (str[i2] != ')') {
                         type_decl = 1;
                     }
-                    set_color(p_start, p, C_STYLE_TYPE);
+                    SET_COLOR(str, start, i, C_STYLE_TYPE);
                     continue;
                 }
 
-                if (*p == '(' || (p[0] == ' ' && p[1] == '(')) {
+                if (str[i] == '(' || (str[i] == ' ' && str[i + 1] == '(')) {
                     /* function call */
                     /* XXX: different styles for call and definition */
-                    set_color(p_start, p, C_STYLE_FUNCTION);
+                    SET_COLOR(str, start, i, C_STYLE_FUNCTION);
                     continue;
                 }
                 /* assume typedef if starting at first column */
-                if (p_start == str)
+                if (start == 0)
                     type_decl = 1;
 
                 if (type_decl) {
-                    if (p_start == str) {
+                    if (start == 0) {
                         /* assume type if first column */
-                        set_color(p_start, p, C_STYLE_TYPE);
+                        SET_COLOR(str, start, i, C_STYLE_TYPE);
                     } else {
-                        set_color(p_start, p, C_STYLE_VARIABLE);
+                        SET_COLOR(str, start, i, C_STYLE_VARIABLE);
                     }
                 }
                 continue;
             }
             break;
         }
-        set_color1(p_start, style);
+        SET_COLOR1(str, start, style);
     }
  the_end:
     /* strip state if not overflowing from a comment */
-    if (!(state & IN_C_COMMENT) && p > str && ((p[-1] & CHAR_MASK) != '\\'))
+    if (!(state & IN_C_COMMENT) && n > 0 && ((str[n - 1] & CHAR_MASK) != '\\'))
         state &= ~(IN_C_COMMENT1 | IN_C_PREPROCESS);
-    *colorize_state_ptr = state;
+    cp->colorize_state = state;
 }
 
 #define MAX_STACK_SIZE  64

Index: htmlsrc.c
===================================================================
RCS file: /sources/qemacs/qemacs/htmlsrc.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- htmlsrc.c   2 Apr 2014 12:58:12 -0000       1.12
+++ htmlsrc.c   5 Apr 2014 15:49:14 -0000       1.13
@@ -76,172 +76,171 @@
     //HTML_STYLE_TEXT       = QE_STYLE_HTML_TEXT,
 };
 
-void htmlsrc_colorize_line(unsigned int *buf, int len, int mode_flags,
-                           int *colorize_state_ptr, int state_only)
+void htmlsrc_colorize_line(QEColorizeContext *cp,
+                           unsigned int *str, int n, int mode_flags)
 {
-    int c, state, js_state, l;
-    unsigned int *p, *p_start, *p_end;
-
-    state = *colorize_state_ptr;
-    p = buf;
-    p_start = p;
-    p_end = p + len;
+    int i = 0, start = i, c, len;
+    int state = cp->colorize_state;
 
     /* Kludge for preprocessed html */
-    if (*p == '#') {
-        p = p_end;
-        set_color(p_start, p, HTML_STYLE_PREPROCESS);
+    if (str[i] == '#') {
+        i = n;
+        SET_COLOR(str, start, i, HTML_STYLE_PREPROCESS);
         goto the_end;
     }
 
-    while (p < p_end) {
-        p_start = p;
-        c = *p;
+    while (i < n) {
+        start = i;
+        c = str[i];
 
         if (state & IN_HTML_SCRIPTTAG) {
-            while (p < p_end) {
-                if (*p++ == '>') {
+            while (i < n) {
+                if (str[i++] == '>') {
                     state = IN_HTML_SCRIPT;
                     break;
                 }
             }
-            set_color(p_start, p, HTML_STYLE_SCRIPT);
+            SET_COLOR(str, start, i, HTML_STYLE_SCRIPT);
             continue;
         }
         if (state & IN_HTML_SCRIPT) {
-            for (; p < p_end; p++) {
-                if (*p == '<' && ustristart(p, "</script>", NULL))
+            for (; i < n; i++) {
+                if (str[i] == '<' && ustristart(str + i, "</script>", NULL))
                     break;
             }
-            js_state = state & ~IN_HTML_SCRIPT;
-            c = *p;     /* save char to set '\0' delimiter */
-            *p = '\0';
-            /* XXX: should have javascript specific colorize_func */
-            c_colorize_line(p_start, p - p_start, CLANG_JS | CLANG_REGEX,
-                            &js_state, state_only);
-            *p = c;
-            state = js_state | IN_HTML_SCRIPT;
-            if (p < p_end) {
-                p_start = p;
-                p += strlen("</script>");
+            state &= ~IN_HTML_SCRIPT;
+            cp->colorize_state = state;
+            c = str[i];     /* save char to set '\0' delimiter */
+            str[i] = '\0';
+            /* XXX: should have js_colorize_func */
+            c_colorize_line(cp, str + start, i - start,
+                            CLANG_JS | CLANG_REGEX);
+            str[i] = c;
+            state = cp->colorize_state;
+            state |= IN_HTML_SCRIPT;
+            if (i < n) {
+                start = i;
+                i += strlen("</script>");
                 state = 0;
-                set_color(p_start, p, HTML_STYLE_SCRIPT);
+                SET_COLOR(str, start, i, HTML_STYLE_SCRIPT);
             }
             continue;
         }
         if (state & IN_HTML_COMMENT) {
-            for (; p < p_end; p++) {
-                if (*p == '-' && p[1] == '-' && p[2] == '>') {
-                    p += 2;
-                    state &= ~IN_HTML_COMMENT;
+            for (; i < n; i++) {
+                if (str[i] == '-' && str[i + 1] == '-' && str[i + 2] == '>') {
+                    i += 3;
+                    state &= ~(IN_HTML_COMMENT | IN_HTML_COMMENT1);
                     break;
                 }
             }
-            set_color(p_start, p, HTML_STYLE_COMMENT);
+            SET_COLOR(str, start, i, HTML_STYLE_COMMENT);
             continue;
         }
         if (state & IN_HTML_COMMENT1) {
-            for (; p < p_end; p++) {
-                if (*p == '>') {
-                    p++;
+            for (; i < n; i++) {
+                if (str[i] == '>') {
+                    i++;
                     state &= ~IN_HTML_COMMENT1;
                     break;
                 }
             }
-            set_color(p_start, p, HTML_STYLE_COMMENT);
+            SET_COLOR(str, start, i, HTML_STYLE_COMMENT);
             continue;
         }
         if (state & IN_HTML_ENTITY) {
-            if ((l = get_html_entity(p)) == 0)
-                p++;
+            if ((len = get_html_entity(str + i)) == 0)
+                i++;
             else
-                p += l;
+                i += len;
             state &= ~IN_HTML_ENTITY;
-            set_color(p_start, p, HTML_TYLE_ENTITY);
+            SET_COLOR(str, start, i, HTML_TYLE_ENTITY);
             continue;
         }
         if (state & (IN_HTML_STRING | IN_HTML_STRING1)) {
-            char delim = (char)((state & IN_HTML_STRING1) ? '\'' : '\"');
+            int delim = (state & IN_HTML_STRING1) ? '\'' : '\"';
 
-            for (; p < p_end; p++) {
-                if (*p == '&' && get_html_entity(p)) {
+            for (; i < n; i++) {
+                if (str[i] == '&' && get_html_entity(str + i)) {
                     state |= IN_HTML_ENTITY;
                     break;
                 }
-                if (*p == delim) {
-                    p++;
+                if (str[i] == delim) {
+                    i++;
                     state &= ~(IN_HTML_STRING | IN_HTML_STRING1);
                     break;
                 }
                 /* Premature end of string */
-                if (*p == '>') {
+                if (str[i] == '>') {
                     state &= ~(IN_HTML_STRING | IN_HTML_STRING1);
                     break;
                 }
             }
-            set_color(p_start, p, HTML_STYLE_STRING);
+            SET_COLOR(str, start, i, HTML_STYLE_STRING);
             continue;
         }
         if (state & IN_HTML_TAG) {
-            for (; p < p_end; p++) {
-                if (*p == '&' && get_html_entity(p)) {
+            for (; i < n; i++) {
+                if (str[i] == '&' && get_html_entity(str + i)) {
                     state |= IN_HTML_ENTITY;
                     break;
                 }
-                if (*p == '\"') {
+                if (str[i] == '\"') {
                     state |= IN_HTML_STRING;
                     break;
                 }
-                if (*p == '\'') {
+                if (str[i] == '\'') {
                     state |= IN_HTML_STRING1;
                     break;
                 }
-                if (*p == '>') {
-                    p++;
+                if (str[i] == '>') {
+                    i++;
                     state &= ~IN_HTML_TAG;
                     break;
                 }
             }
-            set_color(p_start, p, HTML_STYLE_TAG);
+            SET_COLOR(str, start, i, HTML_STYLE_TAG);
             if (state & (IN_HTML_STRING | IN_HTML_STRING1)) {
-                set_color1(p, HTML_STYLE_STRING);
-                p++;
+                SET_COLOR1(str, i, HTML_STYLE_STRING);
+                i++;
             }
             continue;
         }
         /* Plain text stream */
-        for (; p < p_end; p++) {
-            if (*p == '<'
-            &&  (qe_isalpha(p[1])
-            ||   p[1] == '!' || p[1] == '/' || p[1] == '?')) {
-                //set_color(p_start, p, HTML_STYLE_TEXT);
-                p_start = p;
-                if (ustristart(p, "<script", NULL)) {
+        for (; i < n; i++) {
+            if (str[i] == '<'
+            &&  (qe_isalpha(str[i + 1]) || str[i + 1] == '!'
+            ||   str[i + 1] == '/' || str[i + 1] == '?')) {
+                //SET_COLOR(str, start, i, HTML_STYLE_TEXT);
+                start = i;
+                if (ustristart(str + i, "<script", NULL)) {
                     state |= IN_HTML_SCRIPTTAG;
                     break;
                 }
-                if (p[1] == '!') {
+                if (str[i + 1] == '!') {
                     state |= IN_HTML_COMMENT1;
-                    p += 2;
-                    if (*p == '-' && p[1] == '-') {
-                        p += 2;
+                    i += 2;
+                    if (str[i] == '-' && str[i + 1] == '-') {
+                        i += 2;
+                        state &= ~IN_HTML_COMMENT1;
                         state |= IN_HTML_COMMENT;
                     }
-                    set_color(p_start, p, HTML_STYLE_COMMENT);
-                    p_start = p;
-                } else
+                    SET_COLOR(str, start, i, HTML_STYLE_COMMENT);
+                    start = i;
+                } else {
                     state |= IN_HTML_TAG;
+                }
                 break;
             }
-            if (*p == '&' && get_html_entity(p)) {
+            if (str[i] == '&' && get_html_entity(str + i)) {
                 state |= IN_HTML_ENTITY;
                 break;
             }
         }
-        //set_color(p_start, p - p_start, HTML_STYLE_TEXT);
+        //SET_COLOR(str, start, i, HTML_STYLE_TEXT);
     }
  the_end:
-    *colorize_state_ptr = state;
+    cp->colorize_state = state;
 }
 
 static int html_tagcmp(const char *s1, const char *s2)

Index: list.c
===================================================================
RCS file: /sources/qemacs/qemacs/list.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- list.c      1 Apr 2014 07:56:35 -0000       1.13
+++ list.c      5 Apr 2014 15:49:15 -0000       1.14
@@ -39,12 +39,12 @@
     {
         /* highlight the line if the cursor is inside */
         clear_color(buf, len);
-        set_color(buf, buf + len, QE_STYLE_HIGHLIGHT);
+        SET_COLOR(buf, 0, len, QE_STYLE_HIGHLIGHT);
     } else
     if (buf[0] == '*') {
         /* selection */
         clear_color(buf, len);
-        set_color(buf, buf + len, QE_STYLE_SELECTION);
+        SET_COLOR(buf, 0, len, QE_STYLE_SELECTION);
     }
     return len;
 }

Index: orgmode.c
===================================================================
RCS file: /sources/qemacs/qemacs/orgmode.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -b -r1.18 -r1.19
--- orgmode.c   2 Apr 2014 12:58:24 -0000       1.18
+++ orgmode.c   5 Apr 2014 15:49:15 -0000       1.19
@@ -101,10 +101,10 @@
     return 0;
 }
 
-static void org_colorize_line(unsigned int *str, int n, int mode_flags,
-                              int *statep, __unused__ int state_only)
+static void org_colorize_line(QEColorizeContext *cp,
+                              unsigned int *str, int n, int mode_flags)
 {
-    int colstate = *statep;
+    int colstate = cp->colorize_state;
     int i = 0, j = 0, kw, base_style = 0, has_space;
 
     if (colstate & IN_ORG_BLOCK) {
@@ -115,10 +115,12 @@
         } else {
             if (colstate & IN_ORG_LISP) {
                 colstate &= ~(IN_ORG_LISP | IN_ORG_BLOCK);
-                lisp_mode.colorize_func(str, n, 0, &colstate, state_only);
+                cp->colorize_state = colstate;
+                lisp_mode.colorize_func(cp, str, n, 0);
+                colstate = cp->colorize_state;
                 colstate |= IN_ORG_LISP | IN_ORG_BLOCK;
             }
-            *statep = colstate;
+            cp->colorize_state = colstate;
             return;
         }
     }
@@ -284,7 +286,7 @@
     }
 
     colstate &= ~IN_ORG_TABLE;
-    *statep = colstate;
+    cp->colorize_state = colstate;
 }
 
 static int org_is_header_line(EditState *s, int offset)

Index: qe.h
===================================================================
RCS file: /sources/qemacs/qemacs/qe.h,v
retrieving revision 1.160
retrieving revision 1.161
diff -u -b -r1.160 -r1.161
--- qe.h        2 Apr 2014 13:05:42 -0000       1.160
+++ qe.h        5 Apr 2014 15:49:15 -0000       1.161
@@ -1042,11 +1042,17 @@
                                     unsigned int *buf, int buf_size,
                                     int *offset1, int line_num);
 
+typedef struct QEColorizeContext {
+    EditState *s;
+    int colorize_state;
+    int state_only;
+} QEColorizeContext;
+
 /* colorize a line: this function modifies buf to set the char
  * styles. 'buf' is guaranted to have one more '\0' char after its len.
  */
-typedef void (*ColorizeFunc)(unsigned int *buf, int len, int mode_flags,
-                             int *colorize_state_ptr, int state_only);
+typedef void (*ColorizeFunc)(QEColorizeContext *cp,
+                             unsigned int *buf, int n, int mode_flags);
 
 /* contains all the information necessary to uniquely identify a line,
    to avoid displaying it */
@@ -1944,8 +1950,8 @@
 #define CLANG_YACC   0x40
 #define CLANG_REGEX  0x80
 
-void c_colorize_line(unsigned int *buf, int len, int mode_flags,
-                     int *colorize_state_ptr, int state_only);
+void c_colorize_line(QEColorizeContext *cp,
+                     unsigned int *str, int n, int mode_flags);
 
 /* xml.c */
 
@@ -1953,8 +1959,8 @@
 
 /* htmlsrc.c */
 
-void htmlsrc_colorize_line(unsigned int *buf, int len, int mode_flags,
-                           int *colorize_state_ptr, int state_only);
+void htmlsrc_colorize_line(QEColorizeContext *cp,
+                           unsigned int *str, int n, int mode_flags);
 
 /* html.c */
 
@@ -1966,14 +1972,14 @@
 
 /* extra-modes.c */
 
-void lua_colorize_line(unsigned int *buf, int len, int mode_flags,
-                       int *colorize_state_ptr, int state_only);
-void haskell_colorize_line(unsigned int *buf, int len, int mode_flags,
-                           int *colorize_state_ptr, int state_only);
-void python_colorize_line(unsigned int *buf, int len, int mode_flags,
-                          int *colorize_state_ptr, int state_only);
-void ruby_colorize_line(unsigned int *buf, int len, int mode_flags,
-                        int *colorize_state_ptr, int state_only);
+void lua_colorize_line(QEColorizeContext *cp,
+                       unsigned int *str, int n, int mode_flags);
+void haskell_colorize_line(QEColorizeContext *cp,
+                           unsigned int *str, int n, int mode_flags);
+void python_colorize_line(QEColorizeContext *cp,
+                          unsigned int *str, int n, int mode_flags);
+void ruby_colorize_line(QEColorizeContext *cp,
+                        unsigned int *str, int n, int mode_flags);
 
 /* image.c */
 

Index: dired.c
===================================================================
RCS file: /sources/qemacs/qemacs/dired.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -b -r1.43 -r1.44
--- dired.c     2 Apr 2014 13:17:38 -0000       1.43
+++ dired.c     5 Apr 2014 15:49:15 -0000       1.44
@@ -1013,31 +1013,34 @@
         return 0;
 }
 
-static void dired_colorize_line(unsigned int *str, int n, int mode_flags,
-                                int *statep, int state_only)
+static void dired_colorize_line(QEColorizeContext *cp,
+                                unsigned int *str, int n, int mode_flags)
 {
     const unsigned int *p;
-    int i = 0, j = i, style;
+    int i = 0, start = i, style;
 
-    if (ustrstart(str + i, "  Directory of ", &p)) {
-        j = p - str;
-        SET_COLOR(str, i, j, DIRED_STYLE_HEADER);
-        SET_COLOR(str, j, n, DIRED_STYLE_DIRECTORY);
+    if (ustrstart(str + start, "  Directory of ", &p)) {
+        i = p - (str + start);
+        SET_COLOR(str, start, i, DIRED_STYLE_HEADER);
+        style = DIRED_STYLE_DIRECTORY;
+        start = i;
         i = n;
+        SET_COLOR(str, start, i, style);
     } else
-    if (ustrstart(str + n - 6, " bytes", &p)) {
-        SET_COLOR(str, i, n, DIRED_STYLE_HEADER);
+    if (n >= 6 && ustrstart(str + n - 6, " bytes", &p)) {
+        style = DIRED_STYLE_HEADER;
         i = n;
+        SET_COLOR(str, start, i, style);
     } else {
         style = DIRED_STYLE_FILE;
-        if (str[n - 1] == '/')
+        if (n > 0 && str[n - 1] == '/')
             style = DIRED_STYLE_DIRECTORY;
-        for (j = n; j > 2; j--) {
-            if (str[j - 1] == ' ' && str[j - 2] == ' ')
+        for (start = n; start > 2; start--) {
+            if (str[start - 1] == ' ' && str[start - 2] == ' ')
                 break;
         }
-        SET_COLOR(str, j, n, style);
         i = n;
+        SET_COLOR(str, start, i, style);
     }
 }
 

Index: latex-mode.c
===================================================================
RCS file: /sources/qemacs/qemacs/latex-mode.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -b -r1.45 -r1.46
--- latex-mode.c        2 Apr 2014 12:58:23 -0000       1.45
+++ latex-mode.c        5 Apr 2014 15:49:15 -0000       1.46
@@ -33,106 +33,96 @@
 /* TODO: add state handling to allow colorization of elements longer
  * than one line (eg, multi-line functions and strings)
  */
-static void latex_colorize_line(unsigned int *buf, __unused__ int len,
-                                __unused__ int mode_flags,
-                                int *colorize_state_ptr,
-                                __unused__ int state_only)
+static void latex_colorize_line(QEColorizeContext *cp,
+                                unsigned int *str, int n, int mode_flags)
 {
-    int c, state;
-    unsigned int *p, *p_start;
-
-    state = *colorize_state_ptr;
-    p = buf;
-    p_start = p;
+    int i = 0, start, c;
+    int state = cp->colorize_state;
 
     for (;;) {
-        p_start = p;
-        c = *p;
+        start = i;
+        c = str[i++];
         switch (c) {
         case '\0':
         case '\n':      /* Should not happen */
             goto the_end;
         case '`':
-            p++;
             /* a ``string'' */
-            if (*p == '`') {
+            if (str[i] == '`') {
                 for (;;) {
-                    p++;
-                    if (*p == '\0') {
+                    i++;
+                    if (str[i] == '\0') {
                         /* Should either flag an error or propagate
                          * string style to the next line
                          */
                         break;
                     }
-                    if (*p == '\'' && p[1] == '\'') {
-                        p += 2;
+                    if (str[i] == '\'' && str[i + 1] == '\'') {
+                        i += 2;
                         break;
                     }
                 }
-                set_color(p_start, p, LATEX_STYLE_STRING);
+                SET_COLOR(str, start, i, LATEX_STYLE_STRING);
             }
             break;
         case '\\':
-            p++;
             /* \function[keyword]{variable} */
-            if (*p == '\'' || *p == '\"' || *p == '~' || *p == '%' || *p == 
'\\') {
-                p++;
+            if (str[i] == '\'' || str[i] == '\"' || str[i] == '~'
+            ||  str[i] == '%' || str[i] == '\\') {
+                i++;
             } else {
-                while (*p != '\0' && *p != '{' && *p != '[' && *p != ' ' && *p 
!= '\\')
-                    p++;
+                while (str[i] != '\0' && str[i] != '{' && str[i] != '['
+                &&     str[i] != ' ' && str[i] != '\\') {
+                    i++;
             }
-            set_color(p_start, p, LATEX_STYLE_FUNCTION);
-            while (*p == ' ' || *p == '\t') {
-                /* skip space */
-                p++;
             }
-            while (*p == '{' || *p == '[') {
-                if (*p++ == '[') {
+            SET_COLOR(str, start, i, LATEX_STYLE_FUNCTION);
+            while (qe_isblank(str[i])) {
+                i++;
+            }
+            while (str[i] == '{' || str[i] == '[') {
+                if (str[i++] == '[') {
                     /* handle [keyword] */
-                    p_start = p;
-                    while (*p != '\0' && *p != ']')
-                        p++;
-                    set_color(p_start, p, LATEX_STYLE_KEYWORD);
-                    if (*p == ']')
-                        p++;
+                    start = i;
+                    while (str[i] != '\0' && str[i] != ']')
+                        i++;
+                    SET_COLOR(str, start, i, LATEX_STYLE_KEYWORD);
+                    if (str[i] == ']')
+                        i++;
                 } else {
                     int braces = 0;
                     /* handle {variable} */
-                    p_start = p;
-                    while (*p != '\0') {
-                        if (*p == '{') {
+                    start = i;
+                    while (str[i] != '\0') {
+                        if (str[i] == '{') {
                             braces++;
                         } else
-                        if (*p == '}') {
+                        if (str[i] == '}') {
                             if (braces-- == 0)
                                 break;
                         }
-                        p++;
+                        i++;
                     }
-                    set_color(p_start, p, LATEX_STYLE_VARIABLE);
-                    if (*p == '}')
-                        p++;
+                    SET_COLOR(str, start, i, LATEX_STYLE_VARIABLE);
+                    if (str[i] == '}')
+                        i++;
                 }
-                while (*p == ' ' || *p == '\t') {
-                    /* skip space */
-                    p++;
+                while (qe_isblank(str[i])) {
+                    i++;
                 }
             }
             break;
         case '%':
-            p++;
             /* line comment */
-            while (*p != '\0')
-                p++;
-            set_color(p_start, p, LATEX_STYLE_COMMENT);
+            i = n;
+            SET_COLOR(str, start, i, LATEX_STYLE_COMMENT);
             break;
         default:
-            p++;
             break;
         }
     }
  the_end:
-    *colorize_state_ptr = state;
+    cp->colorize_state = state;
 }
 
 static int latex_mode_probe(ModeDef *mode, ModeProbeData *p)

Index: makemode.c
===================================================================
RCS file: /sources/qemacs/qemacs/makemode.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- makemode.c  2 Apr 2014 12:58:20 -0000       1.15
+++ makemode.c  5 Apr 2014 15:49:15 -0000       1.16
@@ -54,17 +54,19 @@
     MAKEFILE_STYLE_MACRO      = QE_STYLE_TYPE,
 };
 
-static void makefile_colorize_line(unsigned int *str, int n, int mode_flags,
-                                   int *statep, int state_only)
+static void makefile_colorize_line(QEColorizeContext *cp,
+                                   unsigned int *str, int n, int mode_flags)
 {
     char buf[32];
     int i = 0, j = i, level;
 
-    if (qe_isalnum_(str[0])) {
+    if (qe_isalnum_(str[i])) {
         get_word_lc(buf, countof(buf), str);
         if (strfind("ifeq|ifneq|ifdef|ifndef|include|else|endif", buf))
             goto preprocess;
     }
+    if (str[i] == '-' && ustristart(str + i + 1, "include ", NULL))
+        goto preprocess;
 
     while (i < n) {
         switch (str[i]) {

Index: perl.c
===================================================================
RCS file: /sources/qemacs/qemacs/perl.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -b -r1.16 -r1.17
--- perl.c      2 Apr 2014 12:58:23 -0000       1.16
+++ perl.c      5 Apr 2014 15:49:15 -0000       1.17
@@ -104,11 +104,11 @@
     return j;
 }
 
-static void perl_colorize_line(unsigned int *str, int n, int mode_flags,
-                               int *statep, __unused__ int state_only)
+static void perl_colorize_line(QEColorizeContext *cp,
+                               unsigned int *str, int n, int mode_flags)
 {
     int i = 0, c, c1, c2, j = i, s1, s2, delim = 0;
-    int colstate = *statep;
+    int colstate = cp->colorize_state;
 
     if (colstate & (IN_PERL_STRING1 | IN_PERL_STRING2)) {
         delim = (colstate & IN_PERL_STRING1) ? '\'' : '\"';
@@ -335,7 +335,7 @@
         i++;
         continue;
     }
-    *statep = colstate;
+    cp->colorize_state = colstate;
 }
 
 static int perl_mode_probe(ModeDef *mode, ModeProbeData *p)

Index: script.c
===================================================================
RCS file: /sources/qemacs/qemacs/script.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- script.c    2 Apr 2014 12:58:13 -0000       1.8
+++ script.c    5 Apr 2014 15:49:15 -0000       1.9
@@ -42,14 +42,15 @@
     return j;
 }
 
-static void script_colorize_line(unsigned int *str, int n, int mode_flags,
-                                 int *statep, __unused__ int state_only)
+static void script_colorize_line(QEColorizeContext *cp,
+                                 unsigned int *str, int n, int mode_flags)
 {
-    int i = 0, j, style;
+    int i = 0, j, c, start, style;
 
     style = SCRIPT_STYLE_COMMAND;
 
     while (i < n) {
+        start = i;
         switch (str[i]) {
         case '#':
             if (i > 0 && str[i - 1] == '$')
@@ -57,8 +58,8 @@
             style = SCRIPT_STYLE_COMMENT;
             if (str[i + 1] == '!')
                 style = SCRIPT_STYLE_PREPROCESS;
-            SET_COLOR(str, i, n, style);
             i = n;
+            SET_COLOR(str, start, i, style);
             continue;
         case '`':
             style = SCRIPT_STYLE_BACKTICK;
@@ -68,28 +69,28 @@
             style = SCRIPT_STYLE_STRING;
         has_string:
             /* parse string const */
-            for (j = i + 1; j < n; j++) {
-                if (str[j] == str[i]) {
-                    j++;
+            for (i++; i < n;) {
+                c = str[i++];
+                if (c == '\\' && str[i] == '"' && str[start] == '"')
+                    i++;
+                if (c == str[start])
                     break;
                 }
-            }
-            SET_COLOR(str, i, j, style);
-            i = j;
+            SET_COLOR(str, start, i, style);
             continue;
         case ' ':
         case '\t':
             break;
         default:
-            j = script_var(str, i, n);
-            if (j > i) {
+            i = script_var(str, i, n);
+            if (i > start) {
+                j = i;
                 while (qe_isblank(str[j]))
                     j++;
                 if (str[j] == '=')
                     style = SCRIPT_STYLE_VARIABLE;
-                SET_COLOR(str, i, j, style);
+                SET_COLOR(str, start, i, style);
                 style = SCRIPT_STYLE_TEXT;
-                i = j;
                 continue;
             }
             // Should support << syntax
@@ -98,7 +99,6 @@
             break;
         }
         i++;
-        continue;
     }
 }
 

Index: extra-modes.c
===================================================================
RCS file: /sources/qemacs/qemacs/extra-modes.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- extra-modes.c       2 Apr 2014 12:58:24 -0000       1.11
+++ extra-modes.c       5 Apr 2014 15:49:16 -0000       1.12
@@ -79,12 +79,12 @@
     ASM_STYLE_IDENTIFIER =  QE_STYLE_VARIABLE,
 };
 
-static void asm_colorize_line(unsigned int *str, int n, int mode_flags,
-                              int *statep, __unused__ int state_only)
+static void asm_colorize_line(QEColorizeContext *cp,
+                              unsigned int *str, int n, int mode_flags)
 {
     int i = 0, j, w;
     int wn = 0; /* word number on line */
-    int colstate = *statep;
+    int colstate = cp->colorize_state;
 
     if (colstate) {
         /* skip characters upto and including separator */
@@ -184,7 +184,7 @@
         i++;
         continue;
     }
-    *statep =  colstate;
+    cp->colorize_state = colstate;
 }
 
 static int asm_mode_probe(ModeDef *mode, ModeProbeData *p)
@@ -246,64 +246,58 @@
     BASIC_STYLE_IDENTIFIER =  QE_STYLE_VARIABLE,
 };
 
-static void basic_colorize_line(unsigned int *str, int n, int mode_flags,
-                                int *statep, __unused__ int state_only)
+static void basic_colorize_line(QEColorizeContext *cp,
+                                unsigned int *str, int n, int mode_flags)
 {
-    int i = 0, j;
+    int i = 0, start, c, style;
 
     while (i < n) {
-        switch (str[i]) {
+        start = i;
+        c = str[i++];
+        switch (c) {
         case '\'':
-            if (str[i + 1] == '$')
-                SET_COLOR(str, i, n, BASIC_STYLE_PREPROCESS);
-            else
-                SET_COLOR(str, i, n, BASIC_STYLE_COMMENT);
+            style = BASIC_STYLE_COMMENT;
+            if (str[i] == '$')
+                style = BASIC_STYLE_PREPROCESS;
             i = n;
+            SET_COLOR(str, start, i, style);
             continue;
         case '\"':
             /* parse string const */
-            for (j = i + 1; j < n; j++) {
-                if (str[j] == str[i]) {
-                    j++;
+            while (i < n) {
+                if (str[i++] == c)
                     break;
                 }
-            }
-            SET_COLOR(str, i, j, BASIC_STYLE_STRING);
-            i = j;
+            SET_COLOR(str, start, i, BASIC_STYLE_STRING);
             continue;
         default:
             break;
         }
         /* parse numbers */
-        if (qe_isdigit(str[i])) {
-            for (j = i + 1; j < n; j++) {
-                if (!qe_isalnum(str[j]) && str[j] != '.')
+        if (qe_isdigit(c)) {
+            for (; i < n; i++) {
+                if (!qe_isalnum(str[i]) && str[i] != '.')
                     break;
             }
-            SET_COLOR(str, i, j, BASIC_STYLE_IDENTIFIER);
-            i = j;
+            SET_COLOR(str, start, i, BASIC_STYLE_IDENTIFIER);
             continue;
         }
         /* parse identifiers and keywords */
-        if (qe_isalpha_(str[i])) {
-            for (j = i + 1; j < n; j++) {
-                if (!qe_isalnum_(str[j])) {
-                    if (qe_findchar("$&address@hidden", str[j]))
-                        j++;
+        if (qe_isalpha_(c)) {
+            for (; i < n; i++) {
+                if (!qe_isalnum_(str[i])) {
+                    if (qe_findchar("$&address@hidden", str[i]))
+                        i++;
                     break;
                 }
             }
-            if (is_lc_keyword(str, i, j, basic_keywords)) {
-                SET_COLOR(str, i, j, BASIC_STYLE_KEYWORD);
-                i = j;
+            if (is_lc_keyword(str, start, i, basic_keywords)) {
+                SET_COLOR(str, start, i, BASIC_STYLE_KEYWORD);
                 continue;
             }
-            SET_COLOR(str, i, j, BASIC_STYLE_IDENTIFIER);
-            i = j;
+            SET_COLOR(str, start, i, BASIC_STYLE_IDENTIFIER);
             continue;
         }
-        i++;
-        continue;
     }
 }
 
@@ -369,11 +363,11 @@
     PASCAL_STYLE_FUNCTION =   QE_STYLE_FUNCTION,
 };
 
-static void pascal_colorize_line(unsigned int *str, int n, int mode_flags,
-                                 int *statep, __unused__ int state_only)
+static void pascal_colorize_line(QEColorizeContext *cp,
+                                 unsigned int *str, int n, int mode_flags)
 {
-    int i = 0, j = i, k;
-    int colstate =  *statep;
+    int i = 0, start = i, c, k, style;
+    int colstate = cp->colorize_state;
 
     if (colstate & IN_PASCAL_COMMENT)
         goto in_comment;
@@ -385,122 +379,109 @@
         goto in_comment2;
 
     while (i < n) {
-        switch (str[i]) {
+        start = i;
+        c = str[i++];
+        switch (c) {
         case '/':
-            if (str[i + 1] == '/') {    /* C++ comments, recent extension */
-                SET_COLOR(str, i, n, PASCAL_STYLE_COMMENT);
+            if (str[i] == '/') {    /* C++ comments, recent extension */
                 i = n;
+                SET_COLOR(str, start, i, PASCAL_STYLE_COMMENT);
                 continue;
             }
             break;
         case '{':
             /* check for preprocessor */
-            if (str[i + 1] == '$') {
+            if (str[i] == '$') {
                 colstate = IN_PASCAL_COMMENT1;
-                j = i + 2;
+                i++;
             in_comment1:
-                for (; j < n; j++) {
-                    if (str[j] == '}') {
-                        j += 1;
+                while (i < n) {
+                    if (str[i++] == '}') {
                         colstate = 0;
                         break;
                     }
                 }
-                SET_COLOR(str, i, j, PASCAL_STYLE_PREPROCESS);
-            } else
-            {
+                SET_COLOR(str, start, i, PASCAL_STYLE_PREPROCESS);
+            } else {
                 /* regular comment (recursive?) */
                 colstate = IN_PASCAL_COMMENT;
-                j = i + 1;
             in_comment:
-                for (; j < n; j++) {
-                    if (str[j] == '}') {
-                        j += 1;
+                while (i < n) {
+                    if (str[i++] == '}') {
                         colstate = 0;
                         break;
                     }
                 }
-                SET_COLOR(str, i, j, PASCAL_STYLE_COMMENT);
+                SET_COLOR(str, start, i, PASCAL_STYLE_COMMENT);
             }
-            i = j;
             continue;
         case '(':
             /* check for preprocessor */
-            if (str[i + 1] != '*')
+            if (str[i] != '*')
                 break;
 
             /* regular comment (recursive?) */
             colstate = IN_PASCAL_COMMENT2;
-            j = i + 2;
+            i++;
         in_comment2:
-            for (; j < n; j++) {
-                if (str[j] == '*' && str[j + 1] == ')') {
-                    j += 2;
+            for (; i < n; i++) {
+                if (str[i] == '*' && str[i + 1] == ')') {
+                    i += 2;
                     colstate = 0;
                     break;
                 }
             }
-            SET_COLOR(str, i, j, PASCAL_STYLE_COMMENT);
-            i = j;
+            SET_COLOR(str, start, i, PASCAL_STYLE_COMMENT);
             continue;
         case '\'':
             /* parse string or char const */
-            for (j = i + 1; j < n; j++) {
-                if (str[j] == str[i]) {
-                    j++;
+            while (i < n) {
+                /* XXX: escape sequences? */
+                if (str[i++] == c)
                     break;
                 }
-            }
-            SET_COLOR(str, i, j, PASCAL_STYLE_STRING);
-            i = j;
+            SET_COLOR(str, start, i, PASCAL_STYLE_STRING);
             continue;
         case '#':
             /* parse hex char const */
-            for (j = i + 1; j < n; j++) {
-                if (!qe_isdigit(str[j]))
+            for (; i < n; i++) {
+                if (!qe_isxdigit(str[i]))
                     break;
             }
-            SET_COLOR(str, i, j, PASCAL_STYLE_STRING);
-            i = j;
+            SET_COLOR(str, start, i, PASCAL_STYLE_STRING);
             continue;
         default:
             break;
         }
         /* parse numbers */
-        if (qe_isdigit(str[i]) || str[i] == '$') {
-            for (j = i + 1; j < n; j++) {
-                if (!qe_isalnum(str[j]) && str[j] != '.')
+        if (qe_isdigit(c) || c == '$') {
+            for (; i < n; i++) {
+                if (!qe_isalnum(str[i]) && str[i] != '.')
                     break;
             }
-            SET_COLOR(str, i, j, PASCAL_STYLE_NUMBER);
-            i = j;
+            SET_COLOR(str, start, i, PASCAL_STYLE_NUMBER);
             continue;
         }
         /* parse identifiers and keywords */
-        if (qe_isalpha_(str[i])) {
-            for (j = i + 1; j < n; j++) {
-                if (!qe_isalnum_(str[j]))
+        if (qe_isalpha_(c)) {
+            for (; i < n; i++) {
+                if (!qe_isalnum_(str[i]))
                     break;
             }
-            if (is_lc_keyword(str, i, j, pascal_keywords)) {
-                SET_COLOR(str, i, j, PASCAL_STYLE_KEYWORD);
-                i = j;
+            if (is_lc_keyword(str, start, i, pascal_keywords)) {
+                SET_COLOR(str, start, i, PASCAL_STYLE_KEYWORD);
                 continue;
             }
-            for (k = j; k < n; k++) {
-                if (!qe_isblank(str[k]))
-                    break;
-            }
-            SET_COLOR(str, i, j,
-                      str[k] == '(' ? PASCAL_STYLE_FUNCTION :
-                      PASCAL_STYLE_IDENTIFIER);
-            i = j;
+            style = PASCAL_STYLE_IDENTIFIER;
+            for (k = i; qe_isblank(str[k]); k++)
             continue;
-        }
-        i++;
+            if (str[k] == '(')
+                style = PASCAL_STYLE_FUNCTION;
+            SET_COLOR(str, start, i, style);
         continue;
     }
-    *statep = colstate;
+    }
+    cp->colorize_state = colstate;
 }
 
 static int pascal_mode_probe(ModeDef *mode, ModeProbeData *p)
@@ -544,82 +525,73 @@
     INI_STYLE_PREPROCESS = QE_STYLE_PREPROCESS,
 };
 
-static void ini_colorize_line(unsigned int *str, int n, int mode_flags,
-                              int *statep, __unused__ int state_only)
+static void ini_colorize_line(QEColorizeContext *cp,
+                              unsigned int *str, int n, int mode_flags)
 {
-    int i = 0, j;
-    int bol = 1;
+    int i = 0, start, c, bol = 1;
 
     while (i < n) {
-        switch (str[i]) {
+        start = i;
+        c = str[i++];
+        switch (c) {
         case ';':
             if (!bol)
                 break;
-            SET_COLOR(str, i, n, INI_STYLE_COMMENT);
             i = n;
+            SET_COLOR(str, start, i, INI_STYLE_COMMENT);
             continue;
         case '#':
             if (!bol)
                 break;
-            SET_COLOR(str, i, n, INI_STYLE_PREPROCESS);
             i = n;
+            SET_COLOR(str, start, i, INI_STYLE_PREPROCESS);
             continue;
         case '[':
-            if (i == 0) {
-                SET_COLOR(str, i, n, INI_STYLE_FUNCTION);
+            if (start == 0) {
                 i = n;
+                SET_COLOR(str, start, i, INI_STYLE_FUNCTION);
                 continue;
             }
             break;
         case '\"':
             /* parse string const */
-            for (j = i + 1; j < n; j++) {
-                if (str[j] == '\"') {
-                    j++;
+            while (i < n) {
+                /* XXX: escape sequences? */
+                if (str[i++] == '\"')
                     break;
                 }
-            }
-            SET_COLOR(str, i, j, INI_STYLE_STRING);
-            i = j;
+            SET_COLOR(str, start, i, INI_STYLE_STRING);
             continue;
-        default:
-            if (bol && qe_isspace(str[i])) {
-                i++;
+        case ' ':
+        case '\t':
+            if (bol)
                 continue;
-            }
+            break;
+        default:
             break;
         }
         bol = 0;
         /* parse numbers */
-        if (qe_isdigit(str[i])) {
-            for (j = i + 1; j < n; j++) {
-                if (!qe_isalnum(str[j]))
+        if (qe_isdigit(c)) {
+            for (; i < n; i++) {
+                if (!qe_isalnum(str[i]))
                     break;
             }
-            SET_COLOR(str, i, j, INI_STYLE_NUMBER);
-            i = j;
+            SET_COLOR(str, start, i, INI_STYLE_NUMBER);
             continue;
         }
         /* parse identifiers and keywords */
-        if (i == 0
-        &&  (qe_isalpha_(str[i])
-        ||   str[i] == '@' || str[i] == '$')) {
-            for (j = i + 1; j < n; j++) {
-                if (str[j] == '=')
+        if (start == 0 && (qe_isalpha_(c) || c == '@' || c == '$')) {
+            for (; i < n; i++) {
+                if (str[i] == '=')
                     break;
             }
-            if (j < n) {
-                SET_COLOR(str, i, j, INI_STYLE_IDENTIFIER);
-                i = j;
-                continue;
-            } else {
-                i = n;
-                continue;
-            }
+            if (i < n) {
+                SET_COLOR(str, start, i, INI_STYLE_IDENTIFIER);
         }
-        i++;
         continue;
     }
+    }
 }
 
 static int ini_mode_probe(ModeDef *mode, ModeProbeData *pd)
@@ -692,14 +664,13 @@
     PS_STYLE_IDENTIFIER = QE_STYLE_FUNCTION,
 };
 
-#define ispssep(c)      (qe_findchar(" \t\r\n,()<>[]{}/", c))
 #define wrap 0
 
-static void ps_colorize_line(unsigned int *str, int n, int mode_flags,
-                             int *statep, __unused__ int state_only)
+static void ps_colorize_line(QEColorizeContext *cp,
+                             unsigned int *str, int n, int mode_flags)
 {
-    int i = 0, j;
-    int colstate = *statep;
+    int i = 0, start = i, c;
+    int colstate = cp->colorize_state;
 
     if (colstate & IN_PS_COMMENT)
         goto in_comment;
@@ -710,7 +681,9 @@
     colstate = 0;
 
     while (i < n) {
-        switch (str[i]) {
+        start = i;
+        c = str[i++];
+        switch (c) {
             /* Should deal with '<...>' '<<...>>' '<~...~>' tokens. */
         case '%':
         in_comment:
@@ -718,14 +691,15 @@
                 colstate |= IN_PS_COMMENT;
             else
                 colstate &= ~IN_PS_COMMENT;
-            SET_COLOR(str, i, n, PS_STYLE_COMMENT);
             i = n;
+            SET_COLOR(str, start, i, PS_STYLE_COMMENT);
             continue;
         case '(':
+            colstate++;
         in_string:
             /* parse string skipping embedded \\ */
-            for (j = i; j < n;) {
-                switch (str[j++]) {
+            while (i < n) {
+                switch (str[i++]) {
                 case '(':
                     colstate++;
                     continue;
@@ -735,45 +709,41 @@
                         break;
                     continue;
                 case '\\':
-                    if (j == n)
+                    if (i == n)
                         break;
-                    j++;
+                    i++;
                     continue;
                 default:
                     continue;
                 }
                 break;
             }
-            SET_COLOR(str, i, j, PS_STYLE_STRING);
-            i = j;
+            SET_COLOR(str, start, i, PS_STYLE_STRING);
             continue;
         default:
             break;
         }
         /* parse numbers */
-        if (qe_isdigit(str[i])) {
-            for (j = i + 1; j < n; j++) {
-                if (!qe_isalnum(str[j]) && str[j] != '.')
+        if (qe_isdigit(c)) {
+            for (; i < n; i++) {
+                if (!qe_isalnum(str[i]) && str[i] != '.')
                     break;
             }
-            SET_COLOR(str, i, j, PS_STYLE_NUMBER);
-            i = j;
+            SET_COLOR(str, start, i, PS_STYLE_NUMBER);
             continue;
         }
         /* parse identifiers and keywords */
-        if (qe_isalpha_(str[i])) {
-            for (j = i + 1; j < n; j++) {
-                if (ispssep(str[j]))
+        if (qe_isalpha_(c)) {
+            for (; i < n; i++) {
+                if (qe_findchar(" \t\r\n,()<>[]{}/", str[i]))
                     break;
             }
-            SET_COLOR(str, i, j, PS_STYLE_IDENTIFIER);
-            i = j;
+            SET_COLOR(str, start, i, PS_STYLE_IDENTIFIER);
             continue;
         }
-        i++;
-        continue;
     }
-    *statep = colstate;
+    cp->colorize_state = colstate;
+#undef wrap
 }
 
 static int ps_mode_probe(ModeDef *mode, ModeProbeData *p)
@@ -822,74 +792,72 @@
     SQL_STYLE_PREPROCESS = QE_STYLE_PREPROCESS,
 };
 
-static void sql_colorize_line(unsigned int *str, int n, int mode_flags,
-                              int *statep, __unused__ int state_only)
+static void sql_colorize_line(QEColorizeContext *cp,
+                              unsigned int *str, int n, int mode_flags)
 {
-    int i = 0, j = i;
-    int state = *statep;
+    int i = 0, start = i, c, style;
+    int state = cp->colorize_state;
 
     if (state & IN_SQL_COMMENT)
         goto parse_c_comment;
 
     while (i < n) {
-        switch (str[i]) {
+        start = i;
+        c = str[i++];
+        switch (c) {
         case '/':
-            if (str[i + 1] == '/')
+            if (str[i] == '/')
                 goto line_comment;
-            if (str[i + 1] == '*') {
+            if (str[i] == '*') {
                 /* normal comment */
-                j = i + 2;
+                i++;
             parse_c_comment:
                 state |= IN_SQL_COMMENT;
-                while (j < n) {
-                    if (str[j] == '*' && str[j + 1] == '/') {
-                        j += 2;
+                for (; i < n; i++) {
+                    if (str[i] == '*' && str[i + 1] == '/') {
+                        i += 2;
                         state &= ~IN_SQL_COMMENT;
                         break;
-                    } else {
-                        j++;
                     }
                 }
                 goto comment;
             }
             break;
         case '-':
-            if (str[i + 1] == '-')
+            if (str[i] == '-')
                 goto line_comment;
             break;
         case '#':
         line_comment:
-            j = n;
+            i = n;
         comment:
-            SET_COLOR(str, i, j, SQL_STYLE_COMMENT);
-            i = j;
+            SET_COLOR(str, start, i, SQL_STYLE_COMMENT);
             continue;
         case '\'':
         case '\"':
         case '`':
             /* parse string const */
-            for (j = i + 1; j < n; j++) {
+            for (; i < n; i++) {
                 /* FIXME: Should parse strings more accurately */
-                if (str[j] == '\\' && j + 1 < n) {
-                    j++;
+                if (str[i] == '\\' && i + 1 < n) {
+                    i++;
                     continue;
                 }
-                if (str[j] == str[i]) {
-                    j++;
+                if (str[i] == c) {
+                    i++;
                     break;
                 }
             }
-            SET_COLOR(str, i, j,
-                      str[i] == '`' ? SQL_STYLE_IDENTIFIER : SQL_STYLE_STRING);
-            i = j;
+            style = SQL_STYLE_STRING;
+            if (c == '`')
+                style = SQL_STYLE_IDENTIFIER;
+            SET_COLOR(str, start, i, style);
             continue;
         default:
             break;
         }
-        i++;
-        continue;
     }
-    *statep = state;
+    cp->colorize_state = state;
 }
 
 static int sql_mode_probe(ModeDef *mode, ModeProbeData *p)
@@ -967,11 +935,11 @@
     }
 }
 
-void lua_colorize_line(unsigned int *str, int n, int mode_flags,
-                       int *statep, __unused__ int state_only)
+void lua_colorize_line(QEColorizeContext *cp,
+                       unsigned int *str, int n, int mode_flags)
 {
-    int i = 0, j = i, c, sep = 0, level = 0, level1, klen, style;
-    int state = *statep;
+    int i = 0, start = i, c, sep = 0, level = 0, level1, klen, style;
+    int state = cp->colorize_state;
     char kbuf[32];
 
     if (state & IN_LUA_LONGLIT) {
@@ -992,48 +960,48 @@
     }
 
     while (i < n) {
-        switch (c = str[i]) {
+        start = i;
+        c = str[i++];
+        switch (c) {
         case '-':
-            if (str[i + 1] == '-') {
-                if (str[i + 2] == '['
-                &&  lua_long_bracket(str + i + 2, &level)) {
-                    state = IN_LUA_COMMENT | IN_LUA_LONGLIT | (level & 
IN_LUA_LEVEL);
+            if (str[i] == '-') {
+                if (str[i + 1] == '['
+                &&  lua_long_bracket(str + i + 1, &level)) {
+                    state = IN_LUA_COMMENT | IN_LUA_LONGLIT |
+                            (level & IN_LUA_LEVEL);
                     goto parse_longlit;
                 }
-                SET_COLOR(str, i, n, LUA_STYLE_COMMENT);
-                i = n;
+                SET_COLOR(str, start, i, LUA_STYLE_COMMENT);
                 continue;
             }
             break;
         case '\'':
         case '\"':
             /* parse string const */
-            sep = str[i];
-            j = i + 1;
+            sep = c;
         parse_string:
-            for (; j < n;) {
-                c = str[j++];
+            while (i < n) {
+                c = str[i++];
                 if (c == '\\') {
-                    if (str[j] == 'z' && j + 1 == n) {
+                    if (str[i] == 'z' && i + 1 == n) {
                         /* XXX: partial support for \z */
                         state = (sep == '\'') ? IN_LUA_STRING : IN_LUA_STRING2;
-                        j += 1;
+                        i += 1;
                     } else
-                    if (j == n) {
+                    if (i == n) {
                         state = (sep == '\'') ? IN_LUA_STRING : IN_LUA_STRING2;
                     } else {
-                        j += 1;
+                        i += 1;
                     }
                 } else
                 if (c == sep) {
                     break;
                 }
             }
-            SET_COLOR(str, i, j, LUA_STYLE_STRING);
-            i = j;
+            SET_COLOR(str, start, i, LUA_STYLE_STRING);
             continue;
         case '[':
-            if (lua_long_bracket(str + i, &level)) {
+            if (lua_long_bracket(str + i - 1, &level)) {
                 state = IN_LUA_LONGLIT | (level & IN_LUA_LEVEL);
                 goto parse_longlit;
             }
@@ -1041,57 +1009,50 @@
         parse_longlit:
             style = (state & IN_LUA_COMMENT) ?
                     LUA_STYLE_COMMENT : LUA_STYLE_LONGLIT;
-            for (j = i; j < n; j++) {
-                if (str[j] != ']')
-                    continue;
-                if (lua_long_bracket(str + j, &level1) && level1 == level) {
+            for (; i < n; i++) {
+                if (str[i] == ']'
+                &&  lua_long_bracket(str + i, &level1)
+                &&  level1 == level) {
                     state = 0;
-                    j += level + 2;
+                    i += level + 2;
                     break;
                 }
             }
-            SET_COLOR(str, i, j, style);
-            i = j;
+            SET_COLOR(str, start, i, style);
             continue;
         default:
             if (qe_isdigit(c)) {
                 /* XXX: should parse actual number syntax */
-                for (j = i + 1; j < n; j++) {
-                    if (!qe_isalnum(str[j] && str[j] != '.'))
+                for (; i < n; i++) {
+                    if (!qe_isalnum(str[i] && str[i] != '.'))
                         break;
                 }
-                SET_COLOR(str, i, j, LUA_STYLE_NUMBER);
-                i = j;
+                SET_COLOR(str, start, i, LUA_STYLE_NUMBER);
                 continue;
             }
             if (qe_isalpha_(c)) {
-                for (klen = 0, j = i; qe_isalnum_(str[j]); j++) {
+                for (klen = 0, i--; qe_isalnum_(str[i]); i++) {
                     if (klen < countof(kbuf) - 1)
-                        kbuf[klen++] = str[j];
+                        kbuf[klen++] = str[i];
                 }
                 kbuf[klen] = '\0';
 
                 if (strfind(lua_keywords, kbuf)) {
-                    SET_COLOR(str, i, j, LUA_STYLE_KEYWORD);
-                    i = j;
+                    SET_COLOR(str, start, i, LUA_STYLE_KEYWORD);
                     continue;
                 }
-                while (qe_isblank(str[j]))
-                    j++;
-                if (str[j] == '(') {
-                    SET_COLOR(str, i, j, LUA_STYLE_FUNCTION);
-                    i = j;
+                while (qe_isblank(str[i]))
+                    i++;
+                if (str[i] == '(') {
+                    SET_COLOR(str, start, i, LUA_STYLE_FUNCTION);
                     continue;
                 }
-                i = j;
                 continue;
             }
             break;
         }
-        i++;
-        continue;
     }
-    *statep = state;
+    cp->colorize_state = state;
 }
 
 static int lua_mode_probe(ModeDef *mode, ModeProbeData *p)
@@ -1153,11 +1114,11 @@
     return qe_findchar("!#$%&+./<=>address@hidden|-~:", c);
 }
 
-void haskell_colorize_line(unsigned int *str, int n, int mode_flags,
-                           int *statep, __unused__ int state_only)
+void haskell_colorize_line(QEColorizeContext *cp,
+                           unsigned int *str, int n, int mode_flags)
 {
-    int i = 0, j = i, c, sep = 0, level = 0, klen;
-    int state = *statep;
+    int i = 0, start = i, c, sep = 0, level = 0, klen;
+    int state = cp->colorize_state;
     char kbuf[32];
 
     if (state & IN_HASKELL_COMMENT)
@@ -1166,25 +1127,28 @@
     if (state & IN_HASKELL_STRING) {
         sep = '\"';
         state = 0;
-        while (qe_isspace(str[j]))
-            j++;
-        if (str[j] == '\\')
-            j++;
+        while (qe_isspace(str[i]))
+            i++;
+        if (str[i] == '\\')
+            i++;
         goto parse_string;
     }
 
     while (i < n) {
-        switch (c = str[i]) {
+        start = i;
+        c = str[i++];
+        switch (c) {
         case '-':
-            if (str[i + 1] == '-' && !haskell_is_symbol(str[i + 2])) {
-                SET_COLOR(str, i, n, HASKELL_STYLE_COMMENT);
+            if (str[i] == '-' && !haskell_is_symbol(str[i + 1])) {
                 i = n;
+                SET_COLOR(str, start, i, HASKELL_STYLE_COMMENT);
                 continue;
             }
             goto parse_symbol;
         case '{':
-            if (str[i + 1] == '-') {
+            if (str[i] == '-') {
                 state |= IN_HASKELL_COMMENT;
+                i++;
                 goto parse_comment;
             }
             /* FALL THRU */
@@ -1201,17 +1165,17 @@
             
         parse_comment:
             level = state & IN_HASKELL_LEVEL;
-            for (j = i; j < n; j++) {
+            for (; i < n; i++) {
                 if (str[i] == '{' && str[i + 1] == '-') {
                     level++;
-                    j++;
+                    i++;
                     continue;
                 }
                 if (str[i] == '-' && str[i + 1] == '}') {
-                    j++;
+                    i++;
                     level--;
                     if (level == 0) {
-                        j++;
+                        i++;
                         state &= ~IN_HASKELL_COMMENT;
                         break;
                     }
@@ -1219,113 +1183,100 @@
             }
             state &= ~IN_HASKELL_COMMENT;
             state |= level & IN_HASKELL_COMMENT;
-            SET_COLOR(str, i, j, HASKELL_STYLE_COMMENT);
-            i = j;
+            SET_COLOR(str, start, i, HASKELL_STYLE_COMMENT);
             continue;
 
         case '\'':
         case '\"':
             /* parse string const */
-            sep = str[i];
-            j = i + 1;
+            sep = c;
         parse_string:
-            for (; j < n;) {
-                c = str[j++];
+            while (i < n) {
+                c = str[i++];
                 if (c == '\\') {
-                    if (j == n) {
+                    if (i == n) {
                         if (sep == '\"') {
                             /* XXX: should ignore whitespace */
                             state = IN_HASKELL_STRING;
                         }
                     } else
-                    if (str[j] == '^' && j + 1 < n && str[j + 1] != sep) {
-                        j += 2;
+                    if (str[i] == '^' && i + 1 < n && str[i + 1] != sep) {
+                        i += 2;
                     } else {
-                        j += 1;
+                        i += 1;
                     }
                 } else
                 if (c == sep) {
                     break;
                 }
             }
-            SET_COLOR(str, i, j, HASKELL_STYLE_STRING);
-            i = j;
+            SET_COLOR(str, start, i, HASKELL_STYLE_STRING);
             continue;
 
         default:
             if (qe_isdigit(c)) {
-                j = i + 1;
-                if (c == '0' && qe_tolower(str[j]) == 'o') {
+                if (c == '0' && qe_tolower(str[i]) == 'o') {
                     /* octal numbers */
-                    for (j += 1; qe_isoctdigit(str[j]); j++)
+                    for (i += 1; qe_isoctdigit(str[i]); i++)
                         continue;
                 } else
-                if (c == '0' && qe_tolower(str[j]) == 'x') {
+                if (c == '0' && qe_tolower(str[i]) == 'x') {
                     /* hexadecimal numbers */
-                    for (j += 1; qe_isxdigit(str[j]); j++)
+                    for (i += 1; qe_isxdigit(str[i]); i++)
                         continue;
                 } else {
                     /* decimal numbers */
-                    for (j = i + 1; qe_isdigit(str[j]); j++)
+                    for (; qe_isdigit(str[i]); i++)
                         continue;
-                    if (str[j] == '.' && qe_isdigit(str[j + 1])) {
+                    if (str[i] == '.' && qe_isdigit(str[i + 1])) {
                         /* decimal floats require a digit after the '.' */
-                        for (j = i + 2; qe_isdigit(str[j]); j++)
+                        for (i += 2; qe_isdigit(str[i]); i++)
                             continue;
-                        if (qe_tolower(str[j]) == 'e') {
-                            int k = j + 1;
+                        if (qe_tolower(str[i]) == 'e') {
+                            int k = i + 1;
                             if (str[k] == '+' || str[k] == '-')
                                 k++;
                             if (qe_isdigit(str[k])) {
-                                for (j = k + 1; qe_isdigit(str[j]); j++)
+                                for (i = k + 1; qe_isdigit(str[i]); i++)
                                     continue;
                             }
                         }
                     }
                 }
                 /* XXX: should detect malformed number constants */
-                SET_COLOR(str, i, j, HASKELL_STYLE_NUMBER);
-                i = j;
+                SET_COLOR(str, start, i, HASKELL_STYLE_NUMBER);
                 continue;
             }
             if (qe_isalpha_(c)) {
-                for (klen = 0, j = i;
-                     qe_isalnum_(str[j]) || str[j] == '\'';
-                     j++) {
+                for (klen = 0, i--; qe_isalnum_(str[i]) || str[i] == '\''; 
i++) {
                     if (klen < countof(kbuf) - 1)
-                        kbuf[klen++] = str[j];
+                        kbuf[klen++] = str[i];
                 }
                 kbuf[klen] = '\0';
 
                 if (strfind(haskell_keywords, kbuf)) {
-                    SET_COLOR(str, i, j, HASKELL_STYLE_KEYWORD);
-                    i = j;
+                    SET_COLOR(str, start, i, HASKELL_STYLE_KEYWORD);
                     continue;
                 }
-                while (qe_isblank(str[j]))
-                    j++;
-                if (str[j] == '(') {
-                    SET_COLOR(str, i, j, HASKELL_STYLE_FUNCTION);
-                    i = j;
+                while (qe_isblank(str[i]))
+                    i++;
+                if (str[i] == '(') {
+                    SET_COLOR(str, start, i, HASKELL_STYLE_FUNCTION);
                     continue;
                 }
-                i = j;
                 continue;
             }
         parse_symbol:
             if (haskell_is_symbol(c)) {
-                for (j = i + 1; haskell_is_symbol(str[j]); j++)
+                for (; haskell_is_symbol(str[i]); i++)
                     continue;
-                SET_COLOR(str, i, j, HASKELL_STYLE_SYMBOL);
-                i = j;
+                SET_COLOR(str, start, i, HASKELL_STYLE_SYMBOL);
                 continue;
             }
             break;
         }
-        i++;
-        continue;
     }
-    *statep = state;
+    cp->colorize_state = state;
 }
 
 static int haskell_mode_probe(ModeDef *mode, ModeProbeData *p)
@@ -1385,11 +1336,11 @@
     PYTHON_STYLE_FUNCTION = QE_STYLE_FUNCTION,
 };
 
-void python_colorize_line(unsigned int *str, int n, int mode_flags,
-                          int *statep, __unused__ int state_only)
+void python_colorize_line(QEColorizeContext *cp,
+                          unsigned int *str, int n, int mode_flags)
 {
-    int i = 0, j = i, c, sep = 0, klen;
-    int state = *statep;
+    int i = 0, start = i, c, sep = 0, klen;
+    int state = cp->colorize_state;
     char kbuf[32];
 
     if (state & IN_PYTHON_STRING) {
@@ -1410,34 +1361,35 @@
     }
 
     while (i < n) {
-        switch (c = str[i]) {
+        start = i;
+        c = str[i++];
+        switch (c) {
         case '#':
-            j = n;
-            SET_COLOR(str, i, j, PYTHON_STYLE_COMMENT);
-            i = j;
+            i = n;
+            SET_COLOR(str, start, i, PYTHON_STYLE_COMMENT);
             continue;
             
         case '\'':
         case '\"':
             /* parse string const */
-            j = i;
+            i--;
         has_quote:
-            sep = str[j++];
-            if (str[j] == sep && str[j + 1] == sep) {
+            sep = str[i++];
+            if (str[i] == sep && str[i + 1] == sep) {
                 /* long string */
                 state = (sep == '\"') ? IN_PYTHON_LONG_STRING2 :
                         IN_PYTHON_LONG_STRING;
-                j += 2;
+                i += 2;
             parse_long_string:
-                while (j < n) {
-                    c = str[j++];
+                while (i < n) {
+                    c = str[i++];
                     if (!(state & IN_PYTHON_RAW_STRING) && c == '\\') {
-                        if (j < n) {
-                            j += 1;
+                        if (i < n) {
+                            i += 1;
                         }
                     } else
-                    if (c == sep && str[j] == sep && str[j + 1] == sep) {
-                        j += 2;
+                    if (c == sep && str[i] == sep && str[i + 1] == sep) {
+                        i += 2;
                         state = 0;
                         break;
                     }
@@ -1445,11 +1397,11 @@
             } else {
                 state = (sep == '\"') ? IN_PYTHON_STRING2 : IN_PYTHON_STRING;
             parse_string:
-                while (j < n) {
-                    c = str[j++];
+                while (i < n) {
+                    c = str[i++];
                     if (!(state & IN_PYTHON_RAW_STRING) && c == '\\') {
-                        if (j < n) {
-                            j += 1;
+                        if (i < n) {
+                            i += 1;
                         }
                     } else
                     if (c == sep) {
@@ -1458,117 +1410,107 @@
                     }
                 }
             }
-            SET_COLOR(str, i, j, PYTHON_STYLE_STRING);
-            i = j;
+            SET_COLOR(str, start, i, PYTHON_STYLE_STRING);
             continue;
 
         case '.':
-            if (qe_isdigit(str[i + 1])) {
-                j = i;
+            if (qe_isdigit(str[i]))
                 goto parse_decimal;
-            }
             break;
 
         case 'b':
         case 'B':
-            if (qe_tolower(str[i + 1]) == 'r'
-            &&  (str[i + 2] == '\'' || str[i + 2] == '\"')) {
+            if (qe_tolower(str[i]) == 'r'
+            &&  (str[i + 1] == '\'' || str[i + 1] == '\"')) {
                 state |= IN_PYTHON_RAW_STRING;
-                j = i + 2;
+                i += 1;
                 goto has_quote;
             }
             goto has_alpha;
 
         case 'r':
         case 'R':
-            if (qe_tolower(str[i + 1]) == 'b'
-            &&  (str[i + 2] == '\'' || str[i + 2] == '\"')) {
+            if (qe_tolower(str[i]) == 'b'
+            &&  (str[i + 1] == '\'' || str[i + 1] == '\"')) {
                 state |= IN_PYTHON_RAW_STRING;
-                j = i + 2;
+                i += 1;
                 goto has_quote;
             }
-            if ((str[i + 1] == '\'' || str[i + 1] == '\"')) {
+            if ((str[i] == '\'' || str[i] == '\"')) {
                 state |= IN_PYTHON_RAW_STRING;
-                j = i + 1;
                 goto has_quote;
             }
             goto has_alpha;
 
         default:
             if (qe_isdigit(c)) {
-                j = i + 1;
-                if (c == '0' && qe_tolower(str[j]) == 'b') {
+                if (c == '0' && qe_tolower(str[i]) == 'b') {
                     /* binary numbers */
-                    for (j += 1; qe_isbindigit(str[j]); j++)
+                    for (i += 1; qe_isbindigit(str[i]); i++)
                         continue;
                 } else
-                if (c == '0' && qe_tolower(str[j]) == 'o') {
+                if (c == '0' && qe_tolower(str[i]) == 'o') {
                     /* octal numbers */
-                    for (j += 1; qe_isoctdigit(str[j]); j++)
+                    for (i += 1; qe_isoctdigit(str[i]); i++)
                         continue;
                 } else
-                if (c == '0' && qe_tolower(str[j]) == 'x') {
+                if (c == '0' && qe_tolower(str[i]) == 'x') {
                     /* hexadecimal numbers */
-                    for (j += 1; qe_isxdigit(str[j]); j++)
+                    for (i += 1; qe_isxdigit(str[i]); i++)
                         continue;
                 } else {
                     /* decimal numbers */
-                    for (j = i + 1; qe_isdigit(str[j]); j++)
+                    for (; qe_isdigit(str[i]); i++)
                         continue;
+                    if (str[i] == '.' && qe_isdigit(str[i + 1])) {
+                        i++;
                 parse_decimal:
-                    if (str[j] == '.' && qe_isdigit(str[j + 1])) {
                         /* decimal floats require a digit after the '.' */
-                        for (j = i + 2; qe_isdigit(str[j]); j++)
+                        for (; qe_isdigit(str[i]); i++)
                             continue;
                     }
-                    if (qe_tolower(str[j]) == 'e') {
-                        int k = j + 1;
+                    if (qe_tolower(str[i]) == 'e') {
+                        int k = i + 1;
                         if (str[k] == '+' || str[k] == '-')
                             k++;
                         if (qe_isdigit(str[k])) {
-                            for (j = k + 1; qe_isdigit(str[j]); j++)
+                            for (i = k + 1; qe_isdigit(str[i]); i++)
                                 continue;
                         }
                     }
                 }
-                if (qe_tolower(str[j]) == 'j') {
-                    j++;
+                if (qe_tolower(str[i]) == 'j') {
+                    i++;
                 }
                     
                 /* XXX: should detect malformed number constants */
-                SET_COLOR(str, i, j, PYTHON_STYLE_NUMBER);
-                i = j;
+                SET_COLOR(str, start, i, PYTHON_STYLE_NUMBER);
                 continue;
             }
         has_alpha:
             if (qe_isalpha_(c)) {
-                for (klen = 0, j = i; qe_isalnum_(str[j]); j++) {
+                for (klen = 0, i--; qe_isalnum_(str[i]); i++) {
                     if (klen < countof(kbuf) - 1)
-                        kbuf[klen++] = str[j];
+                        kbuf[klen++] = str[i];
                 }
                 kbuf[klen] = '\0';
 
                 if (strfind(python_keywords, kbuf)) {
-                    SET_COLOR(str, i, j, PYTHON_STYLE_KEYWORD);
-                    i = j;
+                    SET_COLOR(str, start, i, PYTHON_STYLE_KEYWORD);
                     continue;
                 }
-                while (qe_isblank(str[j]))
-                    j++;
-                if (str[j] == '(') {
-                    SET_COLOR(str, i, j, PYTHON_STYLE_FUNCTION);
-                    i = j;
+                while (qe_isblank(str[i]))
+                    i++;
+                if (str[i] == '(') {
+                    SET_COLOR(str, start, i, PYTHON_STYLE_FUNCTION);
                     continue;
                 }
-                i = j;
                 continue;
             }
             break;
         }
-        i++;
-        continue;
     }
-    *statep = state;
+    cp->colorize_state = state;
 }
 
 static int python_mode_probe(ModeDef *mode, ModeProbeData *p)
@@ -1667,12 +1609,12 @@
     return j - i;
 }
 
-void ruby_colorize_line(unsigned int *str, int n, int mode_flags,
-                        int *statep, __unused__ int state_only)
+void ruby_colorize_line(QEColorizeContext *cp,
+                        unsigned int *str, int n, int mode_flags)
 {
-    int i = 0, j = i, c, indent, sig;
+    int i = 0, j, start = i, c, indent, sig, style;
     static int sep, sep0, level;        /* XXX: ugly patch */
-    int state = *statep;
+    int state = cp->colorize_state;
     char kbuf[32];
 
     for (indent = 0; qe_isspace(str[indent]); indent++)
@@ -1680,21 +1622,21 @@
 
     if (state & IN_RUBY_HEREDOC) {
         if (state & IN_RUBY_HD_INDENT) {
-            while (qe_isspace(str[j]))
-                j++;
+            while (qe_isspace(str[i]))
+                i++;
         }
        sig = 0;
-        if (qe_isalpha_(str[j])) {
-            sig = str[j++] % 61;
-            for (; qe_isalnum_(str[j]); j++) {
-                sig = ((sig << 6) + str[j]) % 61;
+        if (qe_isalpha_(str[i])) {
+            sig = str[i++] % 61;
+            for (; qe_isalnum_(str[i]); i++) {
+                sig = ((sig << 6) + str[i]) % 61;
             }
         }
-        for (; qe_isspace(str[j]); j++)
+        for (; qe_isspace(str[i]); i++)
             continue;
-        SET_COLOR(str, i, n, RUBY_STYLE_HEREDOC);
         i = n;
-        if (j > 0 && j == n && (state & IN_RUBY_HD_SIG) == (sig & 
IN_RUBY_HD_SIG))
+        SET_COLOR(str, start, i, RUBY_STYLE_HEREDOC);
+        if (i > 0 && i == n && (state & IN_RUBY_HD_SIG) == (sig & 
IN_RUBY_HD_SIG))
             state &= ~(IN_RUBY_HEREDOC | IN_RUBY_HD_INDENT | IN_RUBY_HD_SIG);
     } else {
         if (state & IN_RUBY_COMMENT)
@@ -1722,12 +1664,11 @@
             if (ustrstart(str + i, "=end", NULL)) {
                 state &= ~IN_RUBY_POD;
             }
-            if (str[i] == '=' && qe_isalpha(str[i + 1])) {
-                SET_COLOR(str, i, n, RUBY_STYLE_KEYWORD);
-            } else {
-                SET_COLOR(str, i, n, RUBY_STYLE_COMMENT);
-            }
+            style = RUBY_STYLE_COMMENT;
+            if (str[i] == '=' && qe_isalpha(str[i + 1]))
+                style = RUBY_STYLE_KEYWORD;
             i = n;
+            SET_COLOR(str, start, i, style);
         }
     }
 
@@ -1737,78 +1678,76 @@
     indent = i;
 
     while (i < n) {
-        switch (c = str[i]) {
+        start = i;
+        c = str[i++];
+        switch (c) {
         case '/':
-            if (str[i + 1] == '*') {
+            if (str[i] == '*') {
                 /* C comment */
-                j = i + 2;
+                i++;
             parse_c_comment:
                 state = IN_RUBY_COMMENT;
-                for (; j < n; j++) {
-                    if (str[j] == '*' && str[j + 1] == '/') {
-                        j += 2;
+                for (; i < n; i++) {
+                    if (str[i] == '*' && str[i + 1] == '/') {
+                        i += 2;
                         state &= ~IN_RUBY_COMMENT;
                         break;
                     }
                 }
                 goto comment;
             }
-            if (i == indent
-            ||  (str[i + 1] != ' ' && str[i + 1] != '='
-            &&   !qe_isalnum(str[i - 1] & CHAR_MASK)
-            &&   str[i - 1] != ')')) {
+            if (start == indent
+            ||  (str[i] != ' ' && str[i] != '='
+            &&   !qe_isalnum(str[i - 2] & CHAR_MASK)
+            &&   str[i - 2] != ')')) {
                 /* XXX: should use context to tell regex from divide */
                 /* parse regex */
-                j = i + 1;
                 state = IN_RUBY_REGEX;
             parse_regex:
-                while (j < n) {
+                while (i < n) {
                     /* XXX: should ignore / inside char classes */
-                    c = str[j++];
+                    c = str[i++];
                     if (c == '\\') {
-                        if (j < n) {
-                            j += 1;
+                        if (i < n) {
+                            i += 1;
                         }
                     } else
-                    if (c == '#' && str[j] == '{') {
+                    if (c == '#' && str[i] == '{') {
                         /* should parse full syntax */
-                        while (j < n && str[j++] != '}')
+                        while (i < n && str[i++] != '}')
                             continue;
                     } else
                     if (c == '/') {
-                        while (qe_findchar("ensuimox", str[j])) {
-                            j++;
+                        while (qe_findchar("ensuimox", str[i])) {
+                            i++;
                         }
                         state = 0;
                         break;
                     }
                 }
-                SET_COLOR(str, i, j, RUBY_STYLE_REGEX);
-                i = j;
+                SET_COLOR(str, start, i, RUBY_STYLE_REGEX);
                 continue;
             }
             break;
 
         case '#':
-            j = n;
+            i = n;
         comment:
-            SET_COLOR(str, i, j, RUBY_STYLE_COMMENT);
-            i = j;
+            SET_COLOR(str, start, i, RUBY_STYLE_COMMENT);
             continue;
             
         case '%':
             /* parse alternate string/array syntaxes */
-            if (!qe_isspace(str[i + 1]) && !qe_isalnum(str[i + 1])) {
-                j = i + 1;
+            if (str[i] != '\0' && !qe_isspace(str[i]) && !qe_isalnum(str[i]))
                 goto has_string4;
-            }
-            if (str[i + 1] == 'q' || str[i + 1] == 'Q'
-            ||  str[i + 1] == 'r' || str[i + 1] == 'x'
-            ||  str[i + 1] == 'w' || str[i + 1] == 'W') {
-                j = i + 2;
+
+            if (str[i] == 'q' || str[i] == 'Q'
+            ||  str[i] == 'r' || str[i] == 'x'
+            ||  str[i] == 'w' || str[i] == 'W') {
+                i++;
             has_string4:
                 level = 0;
-                sep = sep0 = str[j++];
+                sep = sep0 = str[i++];
                 if (sep == '{') sep = '}';
                 if (sep == '(') sep = ')';
                 if (sep == '[') sep = ']';
@@ -1816,8 +1755,8 @@
                 /* parse special string const */
                 state = IN_RUBY_STRING4;
             parse_string4:
-                while (j < n) {
-                    c = str[j++];
+                while (i < n) {
+                    c = str[i++];
                     if (c == sep) {
                         if (level-- == 0) {
                             state = level = 0;
@@ -1828,56 +1767,52 @@
                     if (c == sep0) {
                         level++;
                     } else
-                    if (c == '#' && str[j] == '{') {
+                    if (c == '#' && str[i] == '{') {
                         /* XXX: should no parse if %q */
                         /* XXX: should parse full syntax */
-                        while (j < n && str[j++] != '}')
+                        while (i < n && str[i++] != '}')
                             continue;
                     } else
                     if (c == '\\') {
-                        if (j < n) {
-                            j += 1;
+                        if (i < n) {
+                            i += 1;
                         }
                     }
                 }
-                SET_COLOR(str, i, j, RUBY_STYLE_STRING4);
-                i = j;
+                SET_COLOR(str, start, i, RUBY_STYLE_STRING4);
                 continue;
             }
             break;
 
         case '\'':
             /* parse single quoted string const */
-            j = i + 1;
             state = IN_RUBY_STRING;
         parse_string:
-            while (j < n) {
-                c = str[j++];
-                if (c == '\\' && (str[j] == '\\' || str[j] == '\'')) {
-                    j += 1;
+            while (i < n) {
+                c = str[i++];
+                if (c == '\\' && (str[i] == '\\' || str[i] == '\'')) {
+                    i += 1;
                 } else
                 if (c == '\'') {
                     state = 0;
                     break;
                 }
             }
-            SET_COLOR(str, i, j, RUBY_STYLE_STRING);
-            i = j;
+            SET_COLOR(str, start, i, RUBY_STYLE_STRING);
             continue;
 
         case '`':
             /* parse single quoted string const */
-            j = i + 1;
             state = IN_RUBY_STRING3;
         parse_string3:
-            while (j < n) {
-                c = str[j++];
-                if (c == '\\' && (str[j] == '\\' || str[j] == '\'')) {
-                    j += 1;
+            while (i < n) {
+                c = str[i++];
+                if (c == '\\' && (str[i] == '\\' || str[i] == '\'')) {
+                    i += 1;
                 } else
-                if (c == '#' && str[j] == '{') {
+                if (c == '#' && str[i] == '{') {
                     /* should parse full syntax */
-                    while (j < n && str[j++] != '}')
+                    while (i < n && str[i++] != '}')
                         continue;
                 } else
                 if (c == '`') {
@@ -1885,25 +1820,23 @@
                     break;
                 }
             }
-            SET_COLOR(str, i, j, RUBY_STYLE_STRING3);
-            i = j;
+            SET_COLOR(str, start, i, RUBY_STYLE_STRING3);
             continue;
 
         case '\"':
             /* parse double quoted string const */
             c = '\0';
-            j = i + 1;
         parse_string2:
-            while (j < n) {
-                c = str[j++];
+            while (i < n) {
+                c = str[i++];
                 if (c == '\\') {
-                    if (j < n) {
-                        j += 1;
+                    if (i < n) {
+                        i += 1;
                     }
                 } else
-                if (c == '#' && str[j] == '{') {
+                if (c == '#' && str[i] == '{') {
                     /* should parse full syntax */
-                    while (j < n && str[j++] != '}')
+                    while (i < n && str[i++] != '}')
                         continue;
                 } else
                 if (c == '\"') {
@@ -1917,12 +1850,11 @@
                 if (state == 0)
                     state = IN_RUBY_STRING2;
             }
-            SET_COLOR(str, i, j, RUBY_STYLE_STRING2);
-            i = j;
+            SET_COLOR(str, start, i, RUBY_STYLE_STRING2);
             continue;
 
         case '<':
-            if (str[i + 1] == '<') {
+            if (str[i] == '<') {
                 /* XXX: should use context to tell lshift from heredoc:
                  * here documents are introduced by monadic <<.
                  * Monadic use could be detected in some contexts, such
@@ -1933,7 +1865,7 @@
                  * XXX: should parse full here document syntax.
                  */
                 sig = 0;
-                j = i + 2;
+                j = i + 1;
                 if (str[j] == '-') {
                     j++;
                 }
@@ -1963,12 +1895,12 @@
                      */
                     state &= ~(IN_RUBY_HEREDOC | IN_RUBY_HD_INDENT | 
IN_RUBY_HD_SIG);
                     state |= IN_RUBY_HEREDOC;
-                    if (str[i + 2] == '-') {
+                    if (str[i + 1] == '-') {
                         state |= IN_RUBY_HD_INDENT;
                     }
                     state |= (sig & IN_RUBY_HD_SIG);
-                    SET_COLOR(str, i, j, RUBY_STYLE_HEREDOC);
                     i = j;
+                    SET_COLOR(str, start, i, RUBY_STYLE_HEREDOC);
                 }
             }
             break;
@@ -1978,17 +1910,15 @@
             break;
 
         case '.':
-            if (qe_isdigit_(str[i + 1])) {
-                j = i;
+            if (qe_isdigit_(str[i]))
                 goto parse_decimal;
-            }
             break;
 
         case '$':
             /* XXX: should parse precise $ syntax,
              * skip $" and $' for now
              */
-            if (i + 1 < n)
+            if (i < n)
                 i++;
             break;
 
@@ -1997,84 +1927,75 @@
             break;
 
         case '@':
-            j = i + 1;
-            j += ruby_get_name(kbuf, countof(kbuf), str + j);
-            SET_COLOR(str, i, j, RUBY_STYLE_MEMBER);
-            i = j;
+            i += ruby_get_name(kbuf, countof(kbuf), str + i);
+            SET_COLOR(str, start, i, RUBY_STYLE_MEMBER);
             continue;
 
         default:
             if (qe_isdigit(c)) {
-                j = i + 1;
-                if (c == '0' && qe_tolower(str[j]) == 'b') {
+                if (c == '0' && qe_tolower(str[i]) == 'b') {
                     /* binary numbers */
-                    for (j += 1; qe_isbindigit(str[j]) || str[j] == '_'; j++)
+                    for (i += 1; qe_isbindigit(str[i]) || str[i] == '_'; i++)
                         continue;
                 } else
-                if (c == '0' && qe_tolower(str[j]) == 'o') {
+                if (c == '0' && qe_tolower(str[i]) == 'o') {
                     /* octal numbers */
-                    for (j += 1; qe_isoctdigit(str[j]) || str[j] == '_'; j++)
+                    for (i += 1; qe_isoctdigit(str[i]) || str[i] == '_'; i++)
                         continue;
                 } else
-                if (c == '0' && qe_tolower(str[j]) == 'x') {
+                if (c == '0' && qe_tolower(str[i]) == 'x') {
                     /* hexadecimal numbers */
-                    for (j += 1; qe_isxdigit(str[j]) || str[j] == '_'; j++)
+                    for (i += 1; qe_isxdigit(str[i]) || str[i] == '_'; i++)
                         continue;
                 } else
-                if (c == '0' && qe_tolower(str[j]) == 'd') {
+                if (c == '0' && qe_tolower(str[i]) == 'd') {
                     /* hexadecimal numbers */
-                    for (j += 1; qe_isdigit_(str[j]); j++)
+                    for (i += 1; qe_isdigit_(str[i]); i++)
                         continue;
                 } else {
                     /* decimal numbers */
-                    for (j = i + 1; qe_isdigit_(str[j]); j++)
+                    for (; qe_isdigit_(str[i]); i++)
                         continue;
+                    if (str[i] == '.') {
+                        i++;
                 parse_decimal:
-                    if (str[j] == '.') {
-                        for (j = i + 1; qe_isdigit_(str[j]); j++)
+                        for (; qe_isdigit_(str[i]); i++)
                             continue;
                     }
-                    if (qe_tolower(str[j]) == 'e') {
-                        int k = j + 1;
+                    if (qe_tolower(str[i]) == 'e') {
+                        int k = i + 1;
                         if (str[k] == '+' || str[k] == '-')
                             k++;
                         if (qe_isdigit_(str[k])) {
-                            for (j = k + 1; qe_isdigit_(str[j]); j++)
+                            for (i = k + 1; qe_isdigit_(str[i]); i++)
                                 continue;
                         }
                     }
                 }
-                    
                 /* XXX: should detect malformed number constants */
-                SET_COLOR(str, i, j, RUBY_STYLE_NUMBER);
-                i = j;
+                SET_COLOR(str, start, i, RUBY_STYLE_NUMBER);
                 continue;
             }
             if (qe_isalpha_(c)) {
-                j = i;
-                j += ruby_get_name(kbuf, countof(kbuf), str + j);
+                i--;
+                i += ruby_get_name(kbuf, countof(kbuf), str + i);
 
                 if (strfind(ruby_keywords, kbuf)) {
-                    SET_COLOR(str, i, j, RUBY_STYLE_KEYWORD);
-                    i = j;
+                    SET_COLOR(str, start, i, RUBY_STYLE_KEYWORD);
                     continue;
                 }
-                while (qe_isblank(str[j]))
-                    j++;
-                if (str[j] == '(') {
-                    SET_COLOR(str, i, j, RUBY_STYLE_FUNCTION);
-                    i = j;
+                while (qe_isblank(str[i]))
+                    i++;
+                if (str[i] == '(') {
+                    SET_COLOR(str, start, i, RUBY_STYLE_FUNCTION);
                     continue;
                 }
-                i = j;
                 continue;
             }
             break;
         }
-        i++;
-        continue;
     }
-    *statep = state;
+    cp->colorize_state = state;
 }
 
 static int ruby_mode_probe(ModeDef *mode, ModeProbeData *p)

Index: lisp.c
===================================================================
RCS file: /sources/qemacs/qemacs/lisp.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- lisp.c      2 Apr 2014 12:58:24 -0000       1.9
+++ lisp.c      5 Apr 2014 15:49:16 -0000       1.10
@@ -35,76 +35,75 @@
     LISP_STYLE_STRING  = QE_STYLE_STRING,
 };
 
-static void lisp_colorize_line(unsigned int *str, int n, int mode_flags,
-                               int *statep, __unused__ int state_only)
+static void lisp_colorize_line(QEColorizeContext *cp,
+                               unsigned int *str, int n, int mode_flags)
 {
-    int colstate = *statep;
-    int i = 0, j = 0;
+    int colstate = cp->colorize_state;
+    int i = 0, start = i;
 
     if (colstate & IN_LISP_STRING) {
-        for (j = i; j < n;) {
-            if (str[j] == '\\' && ++j < n) {
-                j++;
+        while (i < n) {
+            if (str[i] == '\\' && ++i < n) {
+                i++;
             } else
-            if (str[j++] == '"') {
+            if (str[i++] == '"') {
                 colstate &= ~IN_LISP_STRING;
                 break;
             }
         }
-        SET_COLOR(str, i, j, LISP_STYLE_STRING);
-        i = j;
+        SET_COLOR(str, start, i, LISP_STYLE_STRING);
     }
     if (colstate & IN_LISP_COMMENT) {
-        for (j = i; j < n; j++) {
-            if (str[j] == '|' && j + 1 < n && str[j + 1] == '#') {
-                j += 2;
+        for (; i < n; i++) {
+            if (str[i] == '|' && str[i + 1] == '#') {
+                i += 2;
                 colstate &= ~IN_LISP_COMMENT;
                 break;
             }
         }
-        SET_COLOR(str, i, j, LISP_STYLE_COMMENT);
-        i = j;
+        SET_COLOR(str, start, i, LISP_STYLE_COMMENT);
     }
     while (i < n) {
-        switch (str[i]) {
+        start = i;
+        switch (str[i++]) {
         case ';':
-            SET_COLOR(str, i, n, LISP_STYLE_COMMENT);
             i = n;
+            SET_COLOR(str, start, i, LISP_STYLE_COMMENT);
             continue;
         case '#':
             /* check for block comment */
-            if (str[i + 1] == '|') {
+            if (str[i] == '|') {
                 colstate |= IN_LISP_COMMENT;
-                for (j = i + 2; j < n; j++) {
-                    if (str[j] == '|' && str[j + 1] == '#') {
-                        j += 2;
+                for (i++; i < n; i++) {
+                    if (str[i] == '|' && str[i + 1] == '#') {
+                        i += 2;
                         colstate &= ~IN_LISP_COMMENT;
                         break;
                     }
                 }
-                SET_COLOR(str, i, j, LISP_STYLE_COMMENT);
-                i = j;
+                SET_COLOR(str, start, i, LISP_STYLE_COMMENT);
                 continue;
             }
             break;
         case '"':
             /* parse string const */
             colstate |= IN_LISP_STRING;
-            for (j = i + 1; j < n;) {
-                if (str[j++] == '"') {
+            while (i < n) {
+                if (str[i] == '\\' && ++i < n) {
+                    i++;
+                } else
+                if (str[i++] == '"') {
                     colstate &= ~IN_LISP_STRING;
                     break;
                 }
             }
-            SET_COLOR(str, i, j, LISP_STYLE_STRING);
-            i = j;
+            SET_COLOR(str, start, i, LISP_STYLE_STRING);
             continue;
         default:
             break;
         }
-        i++;
     }
-    *statep = colstate;
+    cp->colorize_state = colstate;
 }
 
 static int lisp_mode_probe(ModeDef *mode, ModeProbeData *p)

Index: markdown.c
===================================================================
RCS file: /sources/qemacs/qemacs/markdown.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- markdown.c  2 Apr 2014 12:58:13 -0000       1.10
+++ markdown.c  5 Apr 2014 15:49:16 -0000       1.11
@@ -91,11 +91,11 @@
     return 0;
 }
 
-static void mkd_colorize_line(unsigned int *str, int n, int mode_flags,
-                              int *statep, __unused__ int state_only)
+static void mkd_colorize_line(QEColorizeContext *cp,
+                              unsigned int *str, int n, int mode_flags)
 {
-    int colstate = *statep;
-    int level, indent, i = 0, j = 0, base_style = 0;
+    int colstate = cp->colorize_state;
+    int level, indent, i = 0, j, start = i, base_style = 0;
 
     if (colstate & IN_MKD_HTML_BLOCK) {
         if (str[i] != '<' && str[i] != '\0' && !qe_isblank(str[i]))
@@ -106,11 +106,13 @@
     ||  (str[i] == '<' && str[i + 1] != '/')) {
         /* block level HTML markup */
         colstate &= ~IN_MKD_HTML_BLOCK;
-        htmlsrc_colorize_line(str, n, 0, &colstate, state_only);
+        cp->colorize_state = colstate;
+        htmlsrc_colorize_line(cp, str, n, 0);
+        colstate = cp->colorize_state;
         colstate |= IN_MKD_HTML_BLOCK;
         if ((str[i] & CHAR_MASK) == '<' && (str[i + 1] & CHAR_MASK) == '/')
             colstate = 0;
-        *statep = colstate;
+        cp->colorize_state = colstate;
         return;
     }
 
@@ -119,58 +121,62 @@
         if (ustrstart(str + i, "~~~", NULL)
         ||  ustrstart(str + i, "```", NULL)) {
             colstate &= ~(IN_MKD_BLOCK | IN_MKD_LANG);
-            SET_COLOR(str, i, n, MKD_STYLE_TILDE);
             i = n;
+            SET_COLOR(str, start, i, MKD_STYLE_TILDE);
         } else {
             int lang = colstate & IN_MKD_LANG;
+
             colstate &= ~(IN_MKD_BLOCK | IN_MKD_LANG);
+            cp->colorize_state = colstate;
+
             switch (lang) {
             case IN_MKD_C:
-                c_colorize_line(str, n, CLANG_C, &colstate, state_only);
+                c_colorize_line(cp, str, n, CLANG_C);
                 break;
             case IN_MKD_PYTHON:
-                python_colorize_line(str, n, 0, &colstate, state_only);
+                python_colorize_line(cp, str, n, 0);
                 break;
             case IN_MKD_RUBY:
-                ruby_colorize_line(str, n, 0, &colstate, state_only);
+                ruby_colorize_line(cp, str, n, 0);
                 break;
             case IN_MKD_HASKELL:
-                haskell_colorize_line(str, n, 0, &colstate, state_only);
+                haskell_colorize_line(cp, str, n, 0);
                 break;
             case IN_MKD_LUA:
-                lua_colorize_line(str, n, 0, &colstate, state_only);
+                lua_colorize_line(cp, str, n, 0);
                 break;
             default:
                 SET_COLOR(str, i, n, MKD_STYLE_CODE);
                 break;
             }
+            colstate = cp->colorize_state;
             colstate &= ~(IN_MKD_BLOCK | IN_MKD_LANG);
             colstate |= (IN_MKD_BLOCK | lang);
         }
-        *statep = colstate;
+        cp->colorize_state = colstate;
         return;
     }
 
     if (str[i] == '#') {
         /* Check for heading: initial string of '#' followed by ' ' */
-        for (j = i + 1; str[j] == '#'; j++)
+        for (i++; str[i] == '#'; i++)
             continue;
 
-        if (qe_isblank(str[j])) {
-            base_style = MkdBulletStyles[(j - i - 1) % MKD_BULLET_STYLES];
-            SET_COLOR(str, i, j + 1, base_style);
-            i = j + 1;
+        if (qe_isblank(str[i])) {
+            base_style = MkdBulletStyles[(i - start - 1) % MKD_BULLET_STYLES];
+            i++;
+            SET_COLOR(str, start, i, base_style);
         }
     } else
     if (str[i] == '%') {
         /* pandoc extension: line comment */
-        SET_COLOR(str, i, n, MKD_STYLE_COMMENT);
         i = n;
+        SET_COLOR(str, start, i, MKD_STYLE_COMMENT);
     } else
     if (str[i] == '>') {
         /* block quoting */
-        SET_COLOR(str, i, n, MKD_STYLE_BLOCK_QUOTE);
         i = n;
+        SET_COLOR(str, start, i, MKD_STYLE_BLOCK_QUOTE);
     } else
     if (ustrstart(str + i, "~~~", NULL)
     ||  ustrstart(str + i, "```", NULL)) {
@@ -192,25 +198,23 @@
         if (ustrstr(str + i + 3, "ruby")) {
             colstate |= IN_MKD_RUBY;
         }
-        SET_COLOR(str, i, n, MKD_STYLE_TILDE);
         i = n;
+        SET_COLOR(str, start, i, MKD_STYLE_TILDE);
     } else
     if (str[i] == '-') {
         /* dashes underline a heading */
-        for (j = i + 1; str[j] == '-'; j++)
+        for (i++; str[i] == '-'; i++)
             continue;
-        if (j == n) {
-            SET_COLOR(str, i, n, MKD_STYLE_HEADING2);
-            i = n;
+        if (i == n) {
+            SET_COLOR(str, start, i, MKD_STYLE_HEADING2);
         }
     } else
     if (str[i] == '=') {
         /* equal signs indicate a heading */
-        for (j = i + 1; str[j] == '='; j++)
+        for (i++; str[i] == '='; i++)
             continue;
-        if (j == n) {
-            SET_COLOR(str, i, n, MKD_STYLE_HEADING1);
-            i = n;
+        if (i == n) {
+            SET_COLOR(str, start, i, MKD_STYLE_HEADING1);
         }
     } else
     if (str[i] == '|') {
@@ -245,6 +249,7 @@
     }
 
     if (i < n) {
+        start = i;
         /* ignore blank lines for level and code triggers */
         if (indent < level * 4) {
             level = indent >> 2;
@@ -253,8 +258,8 @@
 
         if (indent >= 4) {
             /* Should detect sequel lines in ordered/unordered lists */
-            SET_COLOR(str, i, n, MKD_STYLE_CODE);
             i = n;
+            SET_COLOR(str, start, i, MKD_STYLE_CODE);
         }
     }
 
@@ -270,8 +275,9 @@
         }
         if (j == n && count >= 3) {
             /* Horizontal rule */
-            SET_COLOR(str, i, n, MKD_STYLE_HBAR);
+            start = i;
             i = n;
+            SET_COLOR(str, start, i, MKD_STYLE_HBAR);
         }
     }
 
@@ -285,22 +291,25 @@
         if (str[j] == '.' && qe_isblank(str[j + 1])) {
             level++;
             base_style = MKD_STYLE_DLIST;
-            SET_COLOR(str, i, j, base_style);
+            start = i;
             i = j;
+            SET_COLOR(str, start, i, base_style);
         }
     } else
     if ((str[i] == '-' || str[i] == '*' || str[i] == '+')
     &&  qe_isblank(str[i + 1])) {
+        start = i;
         level++;
         base_style = MKD_STYLE_LIST;
-        SET_COLOR(str, i, j, base_style);
-        i = j;
+        SET_COLOR(str, start, i, base_style);
     }
 
     for (;;) {
         int chunk = 0, chunk_style = base_style;
-        int flags;
-        int c = str[i];
+        int c, flags;
+
+        start = i;
+        c = str[i];
 
         if (c == '\0')
             break;
@@ -351,39 +360,39 @@
             chunk = mkd_scan_chunk(str + i, "<http", ">", 1);
             if (chunk)
                 break;
-            for (flags = 0, j = i + 1; j < n; j++) {
+            for (flags = 0, j = i + 1; j < n;) {
                 if (str[j] == '@')
                     flags |= 1;
-                if (str[j] == '>') {
+                if (str[j++] == '>') {
                     flags |= 2;
                     break;
                 }
             }
             if (flags == 3) {
-                chunk = j + 1;
+                chunk = j;
                 break;
             }
             break;
         case '\\':  /* escape */
             if (strchr("\\`*_{}[]()#+-.!", str[i + 1])) {
-                SET_COLOR(str, i, i + 2, base_style);
                 i += 2;
+                SET_COLOR(str, start, i, base_style);
                 continue;
             }
             break;
         }
         if (chunk) {
-            SET_COLOR(str, i, i + chunk, chunk_style);
             i += chunk;
+            SET_COLOR(str, start, i, chunk_style);
         } else {
-            SET_COLOR1(str, i, base_style);
             i++;
+            SET_COLOR1(str, start, base_style);
         }
     }
 
     colstate &= ~IN_MKD_LEVEL;
     colstate |= (level << MKD_LEVEL_SHIFT) & IN_MKD_LEVEL;
-    *statep = colstate;
+    cp->colorize_state = colstate;
 }
 
 static int mkd_is_header_line(EditState *s, int offset)

Index: qe.c
===================================================================
RCS file: /sources/qemacs/qemacs/qe.c,v
retrieving revision 1.163
retrieving revision 1.164
diff -u -b -r1.163 -r1.164
--- qe.c        2 Apr 2014 13:05:42 -0000       1.163
+++ qe.c        5 Apr 2014 15:49:16 -0000       1.164
@@ -3264,8 +3264,8 @@
 int generic_get_colorized_line(EditState *s, unsigned int *buf, int buf_size,
                                int *offsetp, int line_num)
 {
+    QEColorizeContext cctx;
     int len, l, line, col, offset, bom;
-    int colorize_state;
 
     /* invalidate cache if needed */
     if (s->colorize_max_valid_offset != INT_MAX) {
@@ -3285,6 +3285,9 @@
         }
     }
 
+    memset(&cctx, 0, sizeof(cctx));
+    cctx.s = s;
+
     /* propagate state if needed */
     if (line_num >= s->colorize_nb_valid_lines) {
         if (s->colorize_nb_valid_lines == 0) {
@@ -3292,25 +3295,26 @@
             s->colorize_nb_valid_lines = 1;
         }
         offset = eb_goto_pos(s->b, s->colorize_nb_valid_lines - 1, 0);
-        colorize_state = s->colorize_states[s->colorize_nb_valid_lines - 1];
+        cctx.colorize_state = s->colorize_states[s->colorize_nb_valid_lines - 
1];
+        cctx.state_only = 1;
 
         for (l = s->colorize_nb_valid_lines; l <= line_num; l++) {
             len = eb_get_line(s->b, buf, buf_size, &offset);
             bom = (len > 0 && buf[0] == 0xFEFF);
-            s->colorize_func(buf + bom, len - bom, s->mode_flags,
-                             &colorize_state, 1);
-            s->colorize_states[l] = colorize_state;
+            s->colorize_func(&cctx, buf + bom, len - bom, s->mode_flags);
+            s->colorize_states[l] = cctx.colorize_state;
         }
     }
 
     /* compute line color */
-    colorize_state = s->colorize_states[line_num];
+    cctx.colorize_state = s->colorize_states[line_num];
+    cctx.state_only = 0;
     len = eb_get_line(s->b, buf, buf_size, offsetp);
     bom = (len > 0 && buf[0] == 0xFEFF);
-    s->colorize_func(buf + bom, len - bom, s->mode_flags, &colorize_state, 0);
+    s->colorize_func(&cctx, buf + bom, len - bom, s->mode_flags);
 
     /* XXX: if state is same as previous, minimize invalid region? */
-    s->colorize_states[line_num + 1] = colorize_state;
+    s->colorize_states[line_num + 1] = cctx.colorize_state;
 
     s->colorize_nb_valid_lines = line_num + 2;
     return len;

Index: xml.c
===================================================================
RCS file: /sources/qemacs/qemacs/xml.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- xml.c       2 Apr 2014 12:58:13 -0000       1.17
+++ xml.c       5 Apr 2014 15:49:16 -0000       1.18
@@ -36,15 +36,13 @@
     XML_STYLE_CSS     = QE_STYLE_CSS,
 };
 
-static void xml_colorize_line(unsigned int *buf, int len, int mode_flags,
-                              int *colorize_state_ptr, int state_only)
+static void xml_colorize_line(QEColorizeContext *cp,
+                              unsigned int *str, int n, int mode_flags)
 {
-    int c, state;
-    unsigned int *p, *p_start, *p1;
+    int i = 0, i1, start, c, state;
+    const unsigned int *p;
 
-    state = *colorize_state_ptr;
-    p = buf;
-    p_start = p;
+    state = cp->colorize_state;
 
     /* if already in a state, go directly in the code parsing it */
     if (state & IN_XML_SCRIPT)
@@ -62,41 +60,41 @@
     }
 
     for (;;) {
-        p_start = p;
-        c = *p;
+        start = i;
+        c = str[i++];
 
         if (c == '\0')
             break;
 
         if (c == '<' && state == 0) {
-            p++;
-            if (p[0] == '!' && p[1] == '-' && p[2] == '-') {
-                p += 3;
+            if (str[i] == '!' && str[i + 1] == '-' && str[i + 2] == '-') {
+                i += 3;
                 state = IN_XML_COMMENT;
                 /* wait until end of comment */
             parse_comment:
-                while (*p != '\0') {
-                    if (p[0] == '-' && p[1] == '-' && p[2] == '>') {
-                        p += 3;
+                while (str[i] != '\0') {
+                    if (str[i] == '-' && str[i + 1] == '-'
+                    &&  str[i + 2] == '>') {
+                        i += 3;
                         state = 0;
                         break;
                     } else {
-                        p++;
+                        i++;
                     }
                 }
-                set_color(p_start, p, XML_STYLE_COMMENT);
+                SET_COLOR(str, start, i, XML_STYLE_COMMENT);
             } else {
                 /* we are in a tag */
-                if (ustristart(p, "SCRIPT", (const unsigned int **)&p)) {
+                if (ustristart(str + i, "SCRIPT", &p)) {
                     state = IN_XML_TAG_SCRIPT;
                 } else
-                if (ustristart(p, "STYLE", (const unsigned int **)&p)) {
+                if (ustristart(str + i, "STYLE", &p)) {
                     state = IN_XML_TAG_STYLE;
                 }
             parse_tag:
-                while (*p != '\0') {
-                    if (*p == '>') {
-                        p++;
+                /* XXX: bogus for <style src="toto" /> */
+                while (str[i] != '\0') {
+                    if (str[i++] == '>') {
                         if (state == IN_XML_TAG_SCRIPT)
                             state = IN_XML_SCRIPT;
                         else
@@ -105,77 +103,77 @@
                         else
                             state = 0;
                         break;
-                    } else {
-                        p++;
                     }
                 }
-                set_color(p_start, p, XML_STYLE_TAG);
+                SET_COLOR(str, start, i, XML_STYLE_TAG);
                 if (state == IN_XML_SCRIPT) {
                     /* javascript coloring */
-                    p_start = p;
+                    start = i;
                 parse_script:
-                    for (;;) {
-                        if (*p == '\0') {
+                    for (;; i++) {
+                        if (str[i] == '\0') {
                             state &= ~IN_XML_SCRIPT;
-                            /* XXX: should have javascript specific 
colorize_func */
-                            c_colorize_line(p_start, p - p_start,
-                                CLANG_C | CLANG_REGEX, &state, state_only);
+                            cp->colorize_state = state;
+                            /* XXX: should have js_colorize_func */
+                            c_colorize_line(cp, str + start, i - start,
+                                            CLANG_JS | CLANG_REGEX);
+                            state = cp->colorize_state;
                             state |= IN_XML_SCRIPT;
                             break;
                         } else
-                        if (ustristart(p, "</SCRIPT", (const unsigned int 
**)&p1)) {
-                            while (*p1 != '\0') {
-                                if (*p1++ == '>')
+                        if (ustristart(str + i, "</SCRIPT", &p)) {
+                            i1 = p - str;
+                            /* XXX: bogus for </script LF > */
+                            while (str[i1] != '\0') {
+                                if (str[i1++] == '>')
                                     break;
                             }
+                            c = str[i];
+                            str[i] = '\0';
                             state &= ~IN_XML_SCRIPT;
-                            c = *p;
-                            *p = '\0';
-                            /* XXX: should have javascript specific 
colorize_func */
-                            c_colorize_line(p_start, p - p_start,
-                                CLANG_C | CLANG_REGEX, &state, state_only);
-                            *p = c;
-                            state |= IN_XML_SCRIPT;
-                            set_color(p, p1, XML_STYLE_TAG);
-                            p = p1;
+                            cp->colorize_state = state;
+                            /* XXX: should have js_colorize_func */
+                            c_colorize_line(cp, str + start, i - start,
+                                            CLANG_JS | CLANG_REGEX);
+                            str[i] = c;
                             state = 0;
+                            start = i;
+                            i = i1;
+                            SET_COLOR(str, start, i, XML_STYLE_TAG);
                             break;
-                        } else {
-                            p++;
                         }
                     }
                 } else
                 if (state == IN_XML_STYLE) {
                     /* stylesheet coloring */
-                    p_start = p;
+                    start = i;
                 parse_style:
-                    for (;;) {
-                        if (*p == '\0') {
-                            set_color(p_start, p, XML_STYLE_CSS);
+                    for (;; i++) {
+                        if (str[i] == '\0') {
+                            /* XXX: should use css_colorize_line */
+                            SET_COLOR(str, start, i, XML_STYLE_CSS);
                             break;
                         } else
-                        if (ustristart(p, "</STYLE", (const unsigned int 
**)&p1)) {
-                            while (*p1 != '\0') {
-                                if (*p1++ != '>')
+                        if (ustristart(str + i, "</STYLE", &p)) {
+                            /* XXX: bogus for </style LF > */
+                            i1 = p - str;
+                            while (str[i1] != '\0') {
+                                if (str[i1++] != '>')
                                     break;
                             }
-                            set_color(p_start, p, XML_STYLE_CSS);
-                            set_color(p, p1, XML_STYLE_TAG);
-                            p = p1;
+                            /* XXX: should use css_colorize_line */
+                            SET_COLOR(str, start, i, XML_STYLE_CSS);
+                            SET_COLOR(str, i, i1, XML_STYLE_TAG);
+                            i = i1;
                             state = 0;
                             break;
-                        } else {
-                            p++;
                         }
                     }
                 }
             }
-        } else {
-            /* text */
-            p++;
         }
     }
-    *colorize_state_ptr = state;
+    cp->colorize_state = state;
 }
 
 static int xml_mode_probe(ModeDef *mode, ModeProbeData *p1)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]