diff -r 831928419249 -r c72b250866ab src/highlighter.c --- a/src/highlighter.c Sun Oct 01 14:41:17 2023 +0200 +++ b/src/highlighter.c Wed Jul 10 21:35:37 2024 +0200 @@ -29,12 +29,11 @@ #include "highlighter.h" -#include -#include #include #include #include +#include static void put_htmlescaped(CxBuffer *dest, char c) { if (c == '>') { @@ -106,45 +105,101 @@ /* local information */ size_t sp = (size_t)-1; + int isstring = 0, iscomment = 0, isinclude = 0, parseinclude = 0; char quote = '\0'; int isescaping = 0; - + + int continuation_enabled = 0; + const char* current_highlight = NULL; + + /* define convenience macros */ +#define start_span(cl) \ + current_highlight = cl; \ + cx_bprintf(dest, "", current_highlight) +#define stop_span \ + current_highlight = NULL;\ + cxBufferPutString(dest, "") + /* continue a multi line comment highlighting */ if (hd->multiline_comment) { iscomment = 1; - cxBufferPutString(dest, ""); + start_span("comment"); + } + + /* continue highlighting in case of line continuation */ + if (hd->continue_highlight) { + start_span(hd->continue_highlight); + hd->continue_highlight = NULL; + isinclude = hd->continuation_info & 0x1; + isstring = hd->continuation_info & 0x2; + iscomment = hd->continuation_info & 0x4; + if (hd->continuation_info & 0x10) { + quote = '\''; + } else if (hd->continuation_info & 0x20) { + quote = '\"'; + } + hd->continuation_info = 0; } char c; do { c = src[++sp]; if (c == '\r') continue; + + /* line continuation */ + if (c == '\\') { + /* currently do not support continuations in user includes */ + // TODO: also support user includes + if (!parseinclude) { + continuation_enabled = 1; + } + } else if (continuation_enabled) { + if (!isspace(c)) { + continuation_enabled = 0; + } else if (c == '\n') { + cxBufferPut(dest, '\n'); + hd->continue_highlight = current_highlight; + hd->continuation_info = \ + isinclude | \ + (isstring << 1) | \ + (iscomment << 2); + if (quote == '\'') { + hd->continuation_info |= 0x10; + } else if (quote == '\"') { + hd->continuation_info |= 0x20; + } + stop_span; + continue; + } + } /* comments */ if (!isstring && c == '/') { if (hd->multiline_comment && sp > 0 && src[sp-1] == '*') { iscomment = 0; hd->multiline_comment = 0; - cxBufferPutString(dest, "/"); + cxBufferPut(dest, '/'); + stop_span; continue; } else if (!iscomment && (src[sp+1] == '/' || src[sp+1] == '*')) { iscomment = 1; hd->multiline_comment = (src[sp+1] == '*'); - cxBufferPutString(dest, ""); + start_span("comment"); } } if (iscomment) { if (c == '\n') { - cxBufferPutString(dest, "\n"); + stop_span; + cxBufferPut(dest, '\n'); } else { put_htmlescaped(dest, c); } } else if (isinclude) { if (c == '<') { - cxBufferPutString(dest, - "<"); + start_span("stdinclude"); + cxBufferPutString(dest, "<"); } else if (c == '\"') { if (parseinclude) { cxBufferPutString(dest, "\">"); @@ -158,7 +213,8 @@ parseinclude = 1; } } else if (c == '>') { - cxBufferPutString(dest, ">"); + cxBufferPutString(dest, ">"); + stop_span; } else { if (parseinclude) { cxBufferPut(ifilebuf, c); @@ -172,14 +228,14 @@ put_htmlescaped(dest, c); if (c == quote) { isstring = 0; - cxBufferPutString(dest, ""); + stop_span; } else { put_htmlescaped(dest, c); } } else { isstring = 1; quote = c; - cxBufferPutString(dest, ""); + start_span("string"); put_htmlescaped(dest, c); } } else { @@ -195,24 +251,20 @@ int closespan = 1; cxstring typesuffix = CX_STR("_t"); if (check_keyword(word, ckeywords)) { - cxBufferPutString(dest, - ""); + start_span("keyword"); } else if (cx_strsuffix(word, typesuffix)) { - cxBufferPutString(dest, - ""); + start_span("type"); } else if (word.ptr[0] == '#') { isinclude = !cx_strcmp(word, CX_STR("#include")); - cxBufferPutString(dest, - ""); + start_span("directive"); } else if (check_capsonly(word)) { - cxBufferPutString(dest, - ""); + start_span("macroconst"); } else { closespan = 0; } put_htmlescapedstr(dest, word); if (closespan) { - cxBufferPutString(dest, ""); + stop_span; } } wbuf->pos = wbuf->size = 0; /* reset word buffer */ @@ -225,6 +277,9 @@ isescaping = !isescaping & (c == '\\'); } } while (c && c != '\n'); + +#undef start_span +#undef stop_span } /* Java Highlighter */