summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Williams <andy@andywilliams.me>2017-01-22 21:58:20 +0000
committerAndy Williams <andy@andywilliams.me>2017-01-22 21:58:20 +0000
commite4fef248987840ae95351119ce48b9855148a2cc (patch)
tree286bf129b562148ee67bd666116bceee49c3b07c
parent633bcfbefbd24d1699a10cec537e2209f0e7a7e0 (diff)
downloadefl-e4fef248987840ae95351119ce48b9855148a2cc.tar.gz
elm_code: Syntax highlighting for multiline comments
-rw-r--r--src/lib/elementary/elm_code_syntax.c116
-rw-r--r--src/tests/elementary/elm_code_test_syntax.c24
2 files changed, 125 insertions, 15 deletions
diff --git a/src/lib/elementary/elm_code_syntax.c b/src/lib/elementary/elm_code_syntax.c
index 96becb9236..a0f4a9e1ea 100644
--- a/src/lib/elementary/elm_code_syntax.c
+++ b/src/lib/elementary/elm_code_syntax.c
@@ -10,12 +10,18 @@
typedef struct _Elm_Code_Syntax
{
const char *symbols;
+ const char *comment_single;
+ const char *comment_start;
+ const char *comment_end;
const char *keywords[];
} Elm_Code_Syntax;
static Elm_Code_Syntax _elm_code_syntax_c =
{
- "{}()[]:;*&|!=<->,.",
+ "{}()[]:;/*+&|!=<->,.",
+ "//",
+ "/*",
+ "*/",
{"auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else", "enum", "extern", \
"float", "for", "goto", "if", "int", "long", "register", "return", "short", "signed", "sizeof", "static", \
"struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while", NULL}
@@ -52,19 +58,97 @@ _elm_code_syntax_parse_token(Elm_Code_Syntax *syntax, Elm_Code_Line *line, unsig
}
}
+static Eina_Bool
+_content_starts_with(const char *content, const char *prefix, unsigned int length)
+{
+ unsigned int i;
+ unsigned int prefix_length;
+
+ prefix_length = strlen(prefix);
+ if (!content || length < prefix_length)
+ return EINA_FALSE;
+
+ for (i = 0; i < prefix_length; i++)
+ if (content[i] != prefix[i])
+ return EINA_FALSE;
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_starts_single_comment(Elm_Code_Syntax *syntax, const char *content, unsigned int length)
+{
+ return _content_starts_with(content, syntax->comment_single, length);
+}
+
+static Eina_Bool
+_starts_comment(Elm_Code_Syntax *syntax, const char *content, unsigned int length)
+{
+ return _content_starts_with(content, syntax->comment_start, length);
+}
+
+static Eina_Bool
+_ends_comment(Elm_Code_Syntax *syntax, const char *content, unsigned int length)
+{
+ return _content_starts_with(content, syntax->comment_end, length);
+}
+
+static Elm_Code_Token_Type
+_previous_line_continue_type(Elm_Code_Line *line)
+{
+ Elm_Code_Line *prev;
+ Elm_Code_Token *token;
+ Eina_List *item;
+
+ if (line->number < 2)
+ return ELM_CODE_TOKEN_TYPE_DEFAULT;
+
+ prev = elm_code_file_line_get(line->file, line->number - 1);
+ if (!prev || !prev->tokens)
+ return ELM_CODE_TOKEN_TYPE_DEFAULT;
+
+ EINA_LIST_FOREACH(prev->tokens, item, token)
+ if (token->continues)
+ return token->type;
+
+ return ELM_CODE_TOKEN_TYPE_DEFAULT;
+}
+
EAPI void
elm_code_syntax_parse_line(Elm_Code_Syntax *syntax, Elm_Code_Line *line)
{
- unsigned int i, count, length;
+ unsigned int i, i2, count, length;
const char *content;
const char *sym, *ptr;
+ Elm_Code_Token_Type previous_type;
EINA_SAFETY_ON_NULL_RETURN(syntax);
- content = elm_code_line_text_get(line, &length);
+ i = 0;
+ content = elm_code_line_text_get(line, &length);
+ previous_type = _previous_line_continue_type(line);
+ if (previous_type == ELM_CODE_TOKEN_TYPE_COMMENT)
+ {
+ for (i2 = i; i2 < length; i2++)
+ if (_ends_comment(syntax, content + i2, length - i2))
+ {
+ i2 += strlen(syntax->comment_end) - 1;
+ break;
+ }
+
+ elm_code_line_token_add(line, 1, i2, 1, ELM_CODE_TOKEN_TYPE_COMMENT);
+ if (i2 == length)
+ {
+ Elm_Code_Token *token = eina_list_last_data_get(line->tokens);
+ token->continues = EINA_TRUE;
+ return;
+ }
+ i = i2 + 1;
+ }
+
ptr = content;
count = 0;
- for (i = 0; i < length; i++)
+ for (; i < length; i++)
{
if (_elm_code_text_char_is_whitespace(content[i]))
{
@@ -81,11 +165,31 @@ elm_code_syntax_parse_line(Elm_Code_Syntax *syntax, Elm_Code_Line *line)
elm_code_line_token_add(line, i, length - 1, 1, ELM_CODE_TOKEN_TYPE_PREPROCESSOR);
return;
}
- else if (count == 1 && content[i-1] == '/' && content[i] == '/')
+ else if (_starts_single_comment(syntax, content + i, length - i))
{
- elm_code_line_token_add(line, i - 1, length - 1, 1, ELM_CODE_TOKEN_TYPE_COMMENT);
+ elm_code_line_token_add(line, i, length, 1, ELM_CODE_TOKEN_TYPE_COMMENT);
return;
}
+ else if (_starts_comment(syntax, content + i, length - i))
+ {
+ for (i2 = i+strlen(syntax->comment_start); i2 < length; i2++)
+ if (_ends_comment(syntax, content + i2, length - i2))
+ {
+ i2 += strlen(syntax->comment_end) - 1;
+ break;
+ }
+
+ elm_code_line_token_add(line, i, i2, 1, ELM_CODE_TOKEN_TYPE_COMMENT);
+ if (i2 == length)
+ {
+ Elm_Code_Token *token = eina_list_last_data_get(line->tokens);
+ token->continues = EINA_TRUE;
+ return;
+ }
+ i = i2;
+ count = 0;
+ continue;
+ }
else if (content[i] == '"')
{
unsigned int start = i, end;
diff --git a/src/tests/elementary/elm_code_test_syntax.c b/src/tests/elementary/elm_code_test_syntax.c
index 0eeea6d0c6..8d088789f9 100644
--- a/src/tests/elementary/elm_code_test_syntax.c
+++ b/src/tests/elementary/elm_code_test_syntax.c
@@ -67,6 +67,9 @@ START_TEST (elm_code_syntax_c)
elm_code_widget_syntax_enabled_set(widget, EINA_TRUE);
_append_line(file, "#include <stdio.h>");
+ _append_line(file, "/**");
+ _append_line(file, " * The main method.");
+ _append_line(file, " */");
_append_line(file, "int main(int argc, char **argv)");
_append_line(file, "{");
_append_line(file, " // display a welcome greeting");
@@ -78,22 +81,25 @@ START_TEST (elm_code_syntax_c)
_append_line(file, "}");
_assert_line_token_types(file, 1, 1, (Elm_Code_Token_Type[1]){ELM_CODE_TOKEN_TYPE_PREPROCESSOR});
- _assert_line_token_types(file, 2, 8, (Elm_Code_Token_Type[8]){ELM_CODE_TOKEN_TYPE_KEYWORD, ELM_CODE_TOKEN_TYPE_BRACE,
+ _assert_line_token_types(file, 2, 1, (Elm_Code_Token_Type[1]){ELM_CODE_TOKEN_TYPE_COMMENT});
+ _assert_line_token_types(file, 3, 1, (Elm_Code_Token_Type[1]){ELM_CODE_TOKEN_TYPE_COMMENT});
+ _assert_line_token_types(file, 4, 1, (Elm_Code_Token_Type[1]){ELM_CODE_TOKEN_TYPE_COMMENT});
+ _assert_line_token_types(file, 5, 8, (Elm_Code_Token_Type[8]){ELM_CODE_TOKEN_TYPE_KEYWORD, ELM_CODE_TOKEN_TYPE_BRACE,
ELM_CODE_TOKEN_TYPE_KEYWORD, ELM_CODE_TOKEN_TYPE_BRACE, ELM_CODE_TOKEN_TYPE_KEYWORD, ELM_CODE_TOKEN_TYPE_BRACE,
ELM_CODE_TOKEN_TYPE_BRACE, ELM_CODE_TOKEN_TYPE_BRACE});
- _assert_line_token_types(file, 3, 1, (Elm_Code_Token_Type[1]){ELM_CODE_TOKEN_TYPE_BRACE});
- _assert_line_token_types(file, 4, 1, (Elm_Code_Token_Type[1]){ELM_CODE_TOKEN_TYPE_COMMENT});
- _assert_line_token_types(file, 5, 5, (Elm_Code_Token_Type[5]){ELM_CODE_TOKEN_TYPE_KEYWORD, ELM_CODE_TOKEN_TYPE_BRACE,
+ _assert_line_token_types(file, 6, 1, (Elm_Code_Token_Type[1]){ELM_CODE_TOKEN_TYPE_BRACE});
+ _assert_line_token_types(file, 7, 1, (Elm_Code_Token_Type[1]){ELM_CODE_TOKEN_TYPE_COMMENT});
+ _assert_line_token_types(file, 8, 5, (Elm_Code_Token_Type[5]){ELM_CODE_TOKEN_TYPE_KEYWORD, ELM_CODE_TOKEN_TYPE_BRACE,
ELM_CODE_TOKEN_TYPE_BRACE, ELM_CODE_TOKEN_TYPE_NUMBER, ELM_CODE_TOKEN_TYPE_BRACE});
- _assert_line_token_types(file, 6, 8, (Elm_Code_Token_Type[8]){ELM_CODE_TOKEN_TYPE_BRACE, ELM_CODE_TOKEN_TYPE_STRING,
+ _assert_line_token_types(file, 9, 8, (Elm_Code_Token_Type[8]){ELM_CODE_TOKEN_TYPE_BRACE, ELM_CODE_TOKEN_TYPE_STRING,
ELM_CODE_TOKEN_TYPE_BRACE, ELM_CODE_TOKEN_TYPE_BRACE, ELM_CODE_TOKEN_TYPE_NUMBER, ELM_CODE_TOKEN_TYPE_BRACE,
ELM_CODE_TOKEN_TYPE_BRACE, ELM_CODE_TOKEN_TYPE_BRACE});
- _assert_line_token_types(file, 7, 1, (Elm_Code_Token_Type[1]){ELM_CODE_TOKEN_TYPE_KEYWORD});
- _assert_line_token_types(file, 8, 4, (Elm_Code_Token_Type[4]){ELM_CODE_TOKEN_TYPE_BRACE, ELM_CODE_TOKEN_TYPE_STRING,
+ _assert_line_token_types(file, 10, 1, (Elm_Code_Token_Type[1]){ELM_CODE_TOKEN_TYPE_KEYWORD});
+ _assert_line_token_types(file, 11, 4, (Elm_Code_Token_Type[4]){ELM_CODE_TOKEN_TYPE_BRACE, ELM_CODE_TOKEN_TYPE_STRING,
ELM_CODE_TOKEN_TYPE_BRACE, ELM_CODE_TOKEN_TYPE_BRACE});
- _assert_line_token_types(file, 9, 3, (Elm_Code_Token_Type[3]){ELM_CODE_TOKEN_TYPE_KEYWORD,
+ _assert_line_token_types(file, 12, 3, (Elm_Code_Token_Type[3]){ELM_CODE_TOKEN_TYPE_KEYWORD,
ELM_CODE_TOKEN_TYPE_NUMBER, ELM_CODE_TOKEN_TYPE_BRACE});
- _assert_line_token_types(file, 10, 1, (Elm_Code_Token_Type[1]){ELM_CODE_TOKEN_TYPE_BRACE});
+ _assert_line_token_types(file, 13, 1, (Elm_Code_Token_Type[1]){ELM_CODE_TOKEN_TYPE_BRACE});
elm_code_free(code);
elm_shutdown();