From bc1cfc7b8728290cc2e02eccee5d05502c258c4d Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Thu, 26 Feb 2015 23:19:09 +0000 Subject: [PATCH] elm_code parse: Add standard parsers starting with diff. Allow code instances to have provided parsers added easily. These can be chained to have multiple passes. --- legacy/elm_code/src/bin/elm_code_test_main.c | 50 +++++++ legacy/elm_code/src/lib/elm_code.c | 2 +- .../elm_code/src/lib/elm_code_diff_widget.c | 60 ++++----- legacy/elm_code/src/lib/elm_code_parse.c | 123 +++++++++++++++++- legacy/elm_code/src/lib/elm_code_parse.h | 11 +- legacy/elm_code/src/lib/elm_code_private.h | 2 + legacy/elm_code/src/lib/elm_code_text.c | 4 +- 7 files changed, 205 insertions(+), 47 deletions(-) diff --git a/legacy/elm_code/src/bin/elm_code_test_main.c b/legacy/elm_code/src/bin/elm_code_test_main.c index 97fbb09018..db994e508b 100644 --- a/legacy/elm_code/src/bin/elm_code_test_main.c +++ b/legacy/elm_code/src/bin/elm_code_test_main.c @@ -114,6 +114,32 @@ _elm_code_test_editor_setup(Evas_Object *parent) return widget; } +static Evas_Object * +_elm_code_test_diff_inline_setup(Evas_Object *parent) +{ + char path[PATH_MAX]; + Evas_Object *diff; + Elm_Code *code; + + snprintf(path, sizeof(path), "%s/../edi/data/testdiff.diff", elm_app_data_dir_get()); + + code = elm_code_create(); + elm_code_file_open(code, path); + + diff = eo_add(ELM_CODE_WIDGET_CLASS, parent); + eo_do(diff, + elm_code_widget_code_set(code)); + + evas_object_size_hint_weight_set(diff, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(diff, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(diff); + + elm_code_parser_standard_add(code, ELM_CODE_PARSER_STANDARD_DIFF); + elm_code_file_open(code, path); + + return diff; +} + static Evas_Object * _elm_code_test_diff_setup(Evas_Object *parent) { @@ -145,6 +171,21 @@ _elm_code_test_welcome_editor_cb(void *data, Evas_Object *obj EINA_UNUSED, void NULL, NULL, screen, NULL); } +static void +_elm_code_test_welcome_diff_inline_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Evas_Object *naviframe, *screen; + + naviframe = (Evas_Object *)data; + screen = elm_box_add(naviframe); + evas_object_size_hint_weight_set(screen, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_box_pack_end(screen, _elm_code_test_diff_inline_setup(screen)); + evas_object_show(screen); + + elm_naviframe_item_push(naviframe, "Diff widget (inline)", + NULL, NULL, screen, NULL); +} + static void _elm_code_test_welcome_diff_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { @@ -192,6 +233,15 @@ elm_code_test_win_setup(void) elm_box_pack_end(vbox, button); evas_object_show(button); + button = elm_button_add(vbox); + elm_object_text_set(button, "Diff (inline)"); + evas_object_size_hint_weight_set(button, 0.5, 0.0); + evas_object_size_hint_align_set(button, EVAS_HINT_FILL, 0.5); + evas_object_smart_callback_add(button, "clicked", + _elm_code_test_welcome_diff_inline_cb, naviframe); + elm_box_pack_end(vbox, button); + evas_object_show(button); + button = elm_button_add(vbox); elm_object_text_set(button, "Diff (comparison)"); evas_object_size_hint_weight_set(button, 0.5, 0.25); diff --git a/legacy/elm_code/src/lib/elm_code.c b/legacy/elm_code/src/lib/elm_code.c index cf735778ad..b951d2b1f8 100644 --- a/legacy/elm_code/src/lib/elm_code.c +++ b/legacy/elm_code/src/lib/elm_code.c @@ -33,7 +33,7 @@ elm_code_init(void) goto shutdown_eina; } - // Put here your initialization logic of your library + _elm_code_parse_setup(); eina_log_timing(_elm_code_lib_log_dom, EINA_LOG_STATE_STOP, EINA_LOG_STATE_INIT); diff --git a/legacy/elm_code/src/lib/elm_code_diff_widget.c b/legacy/elm_code/src/lib/elm_code_diff_widget.c index 21790e982e..275eb97c23 100644 --- a/legacy/elm_code/src/lib/elm_code_diff_widget.c +++ b/legacy/elm_code/src/lib/elm_code_diff_widget.c @@ -16,26 +16,30 @@ static void _elm_code_diff_widget_parse_diff_line(Elm_Code_Line *line, Elm_Code_File *left, Elm_Code_File *right) { + const char *content; + int length; + if (line->length < 1) { elm_code_file_line_append(left, "", 0, NULL); elm_code_file_line_append(right, "", 0, NULL); } - if (line->content[0] == '+') + content = elm_code_line_text_get(line, &length); + if (content[0] == '+') { elm_code_file_line_append(left, "", 0, NULL); - elm_code_file_line_append(right, line->content+1, line->length-1, _ELM_CODE_DIFF_WIDGET_TYPE_ADDED); + elm_code_file_line_append(right, content, length, NULL); } - else if (line->content[0] == '-') + else if (content[0] == '-') { - elm_code_file_line_append(left, line->content+1, line->length-1, _ELM_CODE_DIFF_WIDGET_TYPE_REMOVED); + elm_code_file_line_append(left, content, length, NULL); elm_code_file_line_append(right, "", 0, NULL); } else { - elm_code_file_line_append(left, line->content+1, line->length-1, NULL); - elm_code_file_line_append(right, line->content+1, line->length-1, NULL); + elm_code_file_line_append(left, content, length, NULL); + elm_code_file_line_append(right, content, length, NULL); } } @@ -44,47 +48,35 @@ _elm_code_diff_widget_parse_diff(Elm_Code_File *diff, Elm_Code_File *left, Elm_C { Eina_List *item; Elm_Code_Line *line; - int offset; + const char *content; + int offset, length; offset = 0; EINA_LIST_FOREACH(diff->lines, item, line) { - if (line->length > 0 && (line->content[0] == 'd' || line->content[0] == 'i' || line->content[0] == 'n')) + content = elm_code_line_text_get(line, &length); + + if (length > 0 && (content[0] == 'd' || content[0] == 'i' || content[0] == 'n')) { offset = 0; + elm_code_file_line_append(left, content, length, NULL); + elm_code_file_line_append(right, content, length, NULL); + continue; } if (offset == 0) - elm_code_file_line_append(left, line->content+4, line->length-4, _ELM_CODE_DIFF_WIDGET_TYPE_CHANGED); + elm_code_file_line_append(left, content, length, NULL); else if (offset == 1) - elm_code_file_line_append(right, line->content+4, line->length-4, _ELM_CODE_DIFF_WIDGET_TYPE_CHANGED); + elm_code_file_line_append(right, content, length, NULL); else _elm_code_diff_widget_parse_diff_line(line, left, right); offset++; } -} -static Eina_Bool -_elm_code_diff_widget_line_cb(void *data EINA_UNUSED, Eo *obj EINA_UNUSED, - const Eo_Event_Description *desc EINA_UNUSED, void *event_info) -{ - Elm_Code_Line *line; - - line = (Elm_Code_Line *)event_info; - - if (!line->data) - return EO_CALLBACK_CONTINUE; - - if (!strcmp(_ELM_CODE_DIFF_WIDGET_TYPE_ADDED, (char *)line->data)) - line->status = ELM_CODE_STATUS_TYPE_ADDED; - else if (!strcmp(_ELM_CODE_DIFF_WIDGET_TYPE_REMOVED, (char *)line->data)) - line->status = ELM_CODE_STATUS_TYPE_REMOVED; - else if (!strcmp(_ELM_CODE_DIFF_WIDGET_TYPE_CHANGED, (char *)line->data)) - line->status = ELM_CODE_STATUS_TYPE_CHANGED; - - return EO_CALLBACK_CONTINUE; + _elm_code_parse_file(left->parent, left); + _elm_code_parse_file(right->parent, right); } EAPI Evas_Object * @@ -104,8 +96,8 @@ elm_code_diff_widget_add(Evas_Object *parent, Elm_Code *code) wcode1 = elm_code_create(); widget_left = eo_add(ELM_CODE_WIDGET_CLASS, parent); eo_do(widget_left, - elm_code_widget_code_set(wcode1), - eo_event_callback_add(&ELM_CODE_EVENT_LINE_LOAD_DONE, _elm_code_diff_widget_line_cb, NULL)); + elm_code_widget_code_set(wcode1)); + elm_code_parser_standard_add(wcode1, ELM_CODE_PARSER_STANDARD_DIFF); evas_object_size_hint_weight_set(widget_left, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(widget_left, EVAS_HINT_FILL, EVAS_HINT_FILL); @@ -117,8 +109,8 @@ elm_code_diff_widget_add(Evas_Object *parent, Elm_Code *code) wcode2 = elm_code_create(); widget_right = eo_add(ELM_CODE_WIDGET_CLASS, parent); eo_do(widget_right, - elm_code_widget_code_set(wcode2), - eo_event_callback_add(&ELM_CODE_EVENT_LINE_LOAD_DONE, _elm_code_diff_widget_line_cb, NULL)); + elm_code_widget_code_set(wcode2)); + elm_code_parser_standard_add(wcode2, ELM_CODE_PARSER_STANDARD_DIFF); evas_object_size_hint_weight_set(widget_right, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(widget_right, EVAS_HINT_FILL, EVAS_HINT_FILL); diff --git a/legacy/elm_code/src/lib/elm_code_parse.c b/legacy/elm_code/src/lib/elm_code_parse.c index bea1b30e21..f722ac40f0 100644 --- a/legacy/elm_code/src/lib/elm_code_parse.c +++ b/legacy/elm_code/src/lib/elm_code_parse.c @@ -6,6 +6,16 @@ #include "elm_code_private.h" +struct _Elm_Code_Parser +{ + void (*parse_line)(Elm_Code_Line *, void *); + + void (*parse_file)(Elm_Code_File *, void *); + + void *data; +}; + + void _elm_code_parse_line(Elm_Code *code, Elm_Code_Line *line) { @@ -32,6 +42,22 @@ _elm_code_parse_file(Elm_Code *code, Elm_Code_File *file) } } +static Elm_Code_Parser * +_elm_code_parser_new(void (*parse_line)(Elm_Code_Line *, void *), + void (*parse_file)(Elm_Code_File *, void *)) +{ + Elm_Code_Parser *parser; + + parser = calloc(1, sizeof(Elm_Code_Parser)); + if (!parser) + return NULL; + + parser->parse_line = parse_line; + parser->parse_file = parse_file; + + return parser; +} + EAPI void elm_code_parser_add(Elm_Code *code, void (*parse_line)(Elm_Code_Line *, void *), @@ -39,14 +65,105 @@ elm_code_parser_add(Elm_Code *code, { Elm_Code_Parser *parser; - parser = calloc(1, sizeof(Elm_Code_Parser)); + parser = _elm_code_parser_new(parse_line, parse_file); if (!parser) return; - parser->parse_line = parse_line; - parser->parse_file = parse_file; parser->data = data; code->parsers = eina_list_append(code->parsers, parser); } +EAPI void +elm_code_parser_standard_add(Elm_Code *code, Elm_Code_Parser *parser) +{ + if (!parser || !code) + return; + + code->parsers = eina_list_append(code->parsers, parser); +} + +EAPI Elm_Code_Parser * +ELM_CODE_PARSER_STANDARD_DIFF; + +static void +_elm_code_parser_diff_trim_leading(Elm_Code_Line *line, unsigned int count) +{ + char *replace, *old = NULL; + + if (line->modified) + { + old = line->modified; + replace = malloc(sizeof(char) * (line->length - count)); + + strncpy(replace, old + count, line->length - count); + line->modified = replace; + free(old); + } + else + { + line->content += count; + } + + line->length -= count; +} + +static void +_elm_code_parser_diff_parse_line(Elm_Code_Line *line, void *data EINA_UNUSED) +{ + const char *content; + int length; + + content = elm_code_line_text_get(line, &length); + if (length < 1) + return; + + if (content[0] == 'd' || content[0] == 'i' || content[0] == 'n') + { + elm_code_line_status_set(line, ELM_CODE_STATUS_TYPE_CHANGED); + return; + } + + if (content[0] == '+') + elm_code_line_status_set(line, ELM_CODE_STATUS_TYPE_ADDED); + else if (content[0] == '-') + elm_code_line_status_set(line, ELM_CODE_STATUS_TYPE_REMOVED); + + _elm_code_parser_diff_trim_leading(line, 1); +} + +static void +_elm_code_parser_diff_parse_file(Elm_Code_File *file, void *data EINA_UNUSED) +{ + Eina_List *item; + Elm_Code_Line *line; + const char *content; + int length, offset; + + offset = 0; + EINA_LIST_FOREACH(file->lines, item, line) + { + content = elm_code_line_text_get(line, &length); + + if (length > 0 && (content[0] == 'd' || content[0] == 'i' || content[0] == 'n')) + { + offset = 0; + continue; + } + + if (offset <= 1 && (content[0] == '+' || content[0] == '-')) + { + elm_code_line_status_set(line, ELM_CODE_STATUS_TYPE_CHANGED); + _elm_code_parser_diff_trim_leading(line, 3); + } + + offset++; + } +} + +void +_elm_code_parse_setup() +{ + ELM_CODE_PARSER_STANDARD_DIFF = _elm_code_parser_new(_elm_code_parser_diff_parse_line, + _elm_code_parser_diff_parse_file); +} diff --git a/legacy/elm_code/src/lib/elm_code_parse.h b/legacy/elm_code/src/lib/elm_code_parse.h index 7d53f4d289..d991345b5a 100644 --- a/legacy/elm_code/src/lib/elm_code_parse.h +++ b/legacy/elm_code/src/lib/elm_code_parse.h @@ -10,14 +10,9 @@ extern "C" { * @brief These routines are used for handling the parsing of Elm Code content. */ -typedef struct _Elm_Code_Parser -{ - void (*parse_line)(Elm_Code_Line *, void *); +typedef struct _Elm_Code_Parser Elm_Code_Parser; - void (*parse_file)(Elm_Code_File *, void *); - - void *data; -} Elm_Code_Parser; +EAPI Elm_Code_Parser *ELM_CODE_PARSER_STANDARD_DIFF; /**< A provided parser that will mark up diff text */ /** * @brief Parser helper functions. @@ -32,6 +27,8 @@ typedef struct _Elm_Code_Parser EAPI void elm_code_parser_add(Elm_Code *code, void (*parse_line)(Elm_Code_Line *, void *), void (*parse_file)(Elm_Code_File *, void *), void *data); +EAPI void elm_code_parser_standard_add(Elm_Code *code, Elm_Code_Parser *parser); + /** * @} */ diff --git a/legacy/elm_code/src/lib/elm_code_private.h b/legacy/elm_code/src/lib/elm_code_private.h index 1183c2a6fd..68de837372 100644 --- a/legacy/elm_code/src/lib/elm_code_private.h +++ b/legacy/elm_code/src/lib/elm_code_private.h @@ -42,6 +42,8 @@ typedef struct /* Private parser callbacks */ +void _elm_code_parse_setup(); + void _elm_code_parse_line(Elm_Code *code, Elm_Code_Line *line); void _elm_code_parse_file(Elm_Code *code, Elm_Code_File *file); diff --git a/legacy/elm_code/src/lib/elm_code_text.c b/legacy/elm_code/src/lib/elm_code_text.c index 690bb36484..5ba5fa85b9 100644 --- a/legacy/elm_code/src/lib/elm_code_text.c +++ b/legacy/elm_code/src/lib/elm_code_text.c @@ -6,8 +6,8 @@ #include "elm_code_private.h" -EAPI const char -*elm_code_line_text_get(Elm_Code_Line *line, int *length) +EAPI const char * +elm_code_line_text_get(Elm_Code_Line *line, int *length) { if (!line) return NULL;