diff --git a/elm_code/bin/elm_code_test_main.c b/elm_code/bin/elm_code_test_main.c index 33ab70c..95a5214 100644 --- a/elm_code/bin/elm_code_test_main.c +++ b/elm_code/bin/elm_code_test_main.c @@ -29,7 +29,8 @@ _elm_code_test_welcome_setup(Evas_Object *parent) Elm_Code *code; Evas_Object *widget; - code = elm_code_create(elm_code_file_new()); + code = elm_code_create(); + elm_code_file_new(code); widget = elm_code_widget_add(parent, code); elm_code_file_line_append(code->file, "Hello World, Elm Code!"); elm_code_file_line_token_add(code->file, 1, 14, 21, ELM_CODE_TOKEN_TYPE_COMMENT); @@ -60,7 +61,8 @@ _elm_code_test_diff_setup(Evas_Object *parent) evas_object_show(hbox); // left side of diff - code = elm_code_create(elm_code_file_new()); + code = elm_code_create(); + elm_code_file_new(code); widget = elm_code_widget_add(parent, code); elm_code_file_line_append(code->file, "Some content to diff"); @@ -81,7 +83,8 @@ _elm_code_test_diff_setup(Evas_Object *parent) elm_box_pack_end(hbox, widget); // right side of diff - code = elm_code_create(elm_code_file_new()); + code = elm_code_create(); + elm_code_file_new(code); widget = elm_code_widget_add(parent, code); elm_code_file_line_append(code->file, "Some content to diff"); diff --git a/elm_code/lib/Elm_Code.h b/elm_code/lib/Elm_Code.h index fbc0a4b..3ed59fb 100644 --- a/elm_code/lib/Elm_Code.h +++ b/elm_code/lib/Elm_Code.h @@ -91,14 +91,15 @@ EAPI int elm_code_init(void); EAPI int elm_code_shutdown(void); /** - * Create a new Elm Code instance for an existing file + * Create a new Elm Code instance * - * This method creates a new Elm Code instance backing to the specified file. + * This method creates a new Elm Code instance which will need a + * backing file set for storage. * Once an Elm Code has been created you can create widgets that render the content. * * "return an allocated Elm_Code that references the given file */ -EAPI Elm_Code *elm_code_create(Elm_Code_File *file); +EAPI Elm_Code *elm_code_create(); /** * Free an Elm Code instance diff --git a/elm_code/lib/Makefile.am b/elm_code/lib/Makefile.am index 8329e65..5339cc5 100644 --- a/elm_code/lib/Makefile.am +++ b/elm_code/lib/Makefile.am @@ -13,12 +13,14 @@ lib_LTLIBRARIES = libelm_code.la includes_HEADERS = \ elm_code_file.h \ +elm_code_parse.h \ elm_code_widget.h \ Elm_Code.h includesdir = $(includedir)/edi-@VMAJ@ libelm_code_la_SOURCES = \ elm_code_file.c \ +elm_code_parse.c \ elm_code_widget.c \ elm_code.c libelm_code_la_LIBADD = @EFL_LIBS@ -lm diff --git a/elm_code/lib/elm_code.c b/elm_code/lib/elm_code.c index fb40c9f..bd4a148 100644 --- a/elm_code/lib/elm_code.c +++ b/elm_code/lib/elm_code.c @@ -5,6 +5,7 @@ #include #include "Elm_Code.h" +#include "elm_code_parse.h" #include "elm_code_private.h" @@ -65,13 +66,11 @@ elm_code_shutdown(void) } EAPI Elm_Code * -elm_code_create(Elm_Code_File *file) +elm_code_create() { Elm_Code *ret; ret = calloc(1, sizeof(Elm_Code)); - ret->file = file; - file->parent = ret; return ret; } @@ -79,18 +78,23 @@ elm_code_create(Elm_Code_File *file) EAPI void elm_code_free(Elm_Code *code) { - Eina_List *item; Evas_Object *widget; + Elm_Code_Parser *parser; if (code->file) elm_code_file_free(code->file); - EINA_LIST_FOREACH(code->widgets, item, widget) + EINA_LIST_FREE(code->widgets, widget) { evas_object_hide(widget); evas_object_del(widget); } + EINA_LIST_FREE(code->parsers, parser) + { + free(parser); + } + free(code); } diff --git a/elm_code/lib/elm_code_common.h b/elm_code/lib/elm_code_common.h index 3e39c7b..3dc00ed 100644 --- a/elm_code/lib/elm_code_common.h +++ b/elm_code/lib/elm_code_common.h @@ -4,6 +4,8 @@ #include #include +typedef struct _Elm_Code Elm_Code; + EAPI extern const Eo_Event_Description ELM_CODE_EVENT_LINE_SET_DONE; EAPI extern const Eo_Event_Description ELM_CODE_EVENT_FILE_LOAD_DONE; @@ -44,11 +46,12 @@ extern "C" { * @brief Common data structures and constants. */ -typedef struct _Elm_Code +struct _Elm_Code { Elm_Code_File *file; Eina_List *widgets; -} Elm_Code; + Eina_List *parsers; +}; /** * @} diff --git a/elm_code/lib/elm_code_file.c b/elm_code/lib/elm_code_file.c index e649b28..07ae9e2 100644 --- a/elm_code/lib/elm_code_file.c +++ b/elm_code/lib/elm_code_file.c @@ -4,6 +4,7 @@ #include "Elm_Code.h" #include "elm_code_file.h" +#include "elm_code_parse.h" #include "elm_code_private.h" @@ -33,19 +34,24 @@ static void _elm_code_file_line_append_data(Elm_Code_File *file, const char *con file->lines = eina_list_append(file->lines, line); if (file->parent) - elm_code_callback_fire(file->parent, &ELM_CODE_EVENT_LINE_SET_DONE, line); + { + elm_code_parse_line(file->parent, line); + elm_code_callback_fire(file->parent, &ELM_CODE_EVENT_LINE_SET_DONE, line); + } } -EAPI Elm_Code_File *elm_code_file_new() +EAPI Elm_Code_File *elm_code_file_new(Elm_Code *code) { Elm_Code_File *ret; ret = calloc(1, sizeof(Elm_Code_File)); + code->file = ret; + ret->parent = code; return ret; } -EAPI Elm_Code_File *elm_code_file_open(const char *path) +EAPI Elm_Code_File *elm_code_file_open(Elm_Code *code, const char *path) { Elm_Code_File *ret; Eina_File *file; @@ -53,7 +59,7 @@ EAPI Elm_Code_File *elm_code_file_open(const char *path) Eina_Iterator *it; unsigned int lastindex; - ret = elm_code_file_new(); + ret = elm_code_file_new(code); file = eina_file_open(path, EINA_FALSE); ret->file = file; lastindex = 1; @@ -77,7 +83,10 @@ EAPI Elm_Code_File *elm_code_file_open(const char *path) eina_iterator_free(it); if (ret->parent) - elm_code_callback_fire(ret->parent, &ELM_CODE_EVENT_FILE_LOAD_DONE, ret); + { + elm_code_parse_file(ret->parent, ret); + elm_code_callback_fire(ret->parent, &ELM_CODE_EVENT_FILE_LOAD_DONE, ret); + } return ret; } @@ -98,8 +107,6 @@ EAPI void elm_code_file_free(Elm_Code_File *file) EAPI void elm_code_file_close(Elm_Code_File *file) { eina_file_close(file->file); - - elm_code_file_free(file); } EAPI const char *elm_code_file_filename_get(Elm_Code_File *file) diff --git a/elm_code/lib/elm_code_file.h b/elm_code/lib/elm_code_file.h index 0950ed9..19a4725 100644 --- a/elm_code/lib/elm_code_file.h +++ b/elm_code/lib/elm_code_file.h @@ -52,9 +52,9 @@ typedef struct _Elm_Code_File * */ -EAPI Elm_Code_File *elm_code_file_new(); +EAPI Elm_Code_File *elm_code_file_new(Elm_Code *code); -EAPI Elm_Code_File *elm_code_file_open(const char *path); +EAPI Elm_Code_File *elm_code_file_open(Elm_Code *code, const char *path); EAPI void elm_code_file_free(Elm_Code_File *file); diff --git a/elm_code/lib/elm_code_parse.c b/elm_code/lib/elm_code_parse.c new file mode 100644 index 0000000..2b1ddc2 --- /dev/null +++ b/elm_code/lib/elm_code_parse.c @@ -0,0 +1,47 @@ +#ifdef HAVE_CONFIG +# include "config.h" +#endif + +#include "Elm_Code.h" +#include "elm_code_parse.h" + +#include "elm_code_private.h" + +EAPI void elm_code_parse_line(Elm_Code *code, Elm_Code_Line *line) +{ + Elm_Code_Parser *parser; + Eina_List *item; + + EINA_LIST_FOREACH(code->parsers, item, parser) + { + parser->parse_line(line); + } +} + +EAPI void elm_code_parse_file(Elm_Code *code, Elm_Code_File *file) +{ + Elm_Code_Parser *parser; + Eina_List *item; + + EINA_LIST_FOREACH(code->parsers, item, parser) + { + parser->parse_file(file); + } +} + +EAPI void elm_code_parser_add(Elm_Code *code, + void (*parse_line)(Elm_Code_Line *), + void (*parse_file)(Elm_Code_File *)) +{ + Elm_Code_Parser *parser; + + parser = calloc(1, sizeof(Elm_Code_Parser)); + if (!parser) + return; + + parser->parse_line = parse_line; + parser->parse_file = parse_file; + + code->parsers = eina_list_append(code->parsers, parser); +} + diff --git a/elm_code/lib/elm_code_parse.h b/elm_code/lib/elm_code_parse.h new file mode 100644 index 0000000..ab50c34 --- /dev/null +++ b/elm_code/lib/elm_code_parse.h @@ -0,0 +1,49 @@ +#ifndef ELM_CODE_PARSE_H_ +# define ELM_CODE_PARSE_H_ + +#include + +#include "elm_code_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file + * @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 (*parse_file)(Elm_Code_File *); +} Elm_Code_Parser; + +/** + * @brief Parser helper functions. + * @defgroup Parser Hooking in and launching parsers + * + * @{ + * + * Parser functions for marking up elm code. + * + */ + +EAPI void elm_code_parser_add(Elm_Code *code, void (*parse_line)(Elm_Code_Line *), + void (*parse_file)(Elm_Code_File *)); + +EAPI void elm_code_parse_line(Elm_Code *code, Elm_Code_Line *line); + +EAPI void elm_code_parse_file(Elm_Code *code, Elm_Code_File *file); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ELM_CODE_PARSE_H_ */ diff --git a/elm_code/tests/Makefile.am b/elm_code/tests/Makefile.am index 75ae85c..d1edb30 100644 --- a/elm_code/tests/Makefile.am +++ b/elm_code/tests/Makefile.am @@ -7,6 +7,7 @@ elm_code_suite_SOURCES = \ elm_code_file_test_load.c \ elm_code_file_test_memory.c \ elm_code_test_basic.c \ +elm_code_test_parse.c \ elm_code_test_widget.c \ elm_code_suite.c diff --git a/elm_code/tests/elm_code_file_test_load.c b/elm_code/tests/elm_code_file_test_load.c index ff41d24..ad7dc38 100644 --- a/elm_code/tests/elm_code_file_test_load.c +++ b/elm_code/tests/elm_code_file_test_load.c @@ -9,13 +9,16 @@ START_TEST (elm_code_file_load) char *path = "elm_code/tests/testfile.txt"; char real[EINA_PATH_MAX]; Elm_Code_File *file; + Elm_Code *code; - file = elm_code_file_open(path); + code = elm_code_create(); + file = elm_code_file_open(code, path); realpath(path, real); ck_assert_str_eq(basename(path), elm_code_file_filename_get(file)); ck_assert_str_eq(real, elm_code_file_path_get(file)); elm_code_file_close(file); + elm_code_free(code); } END_TEST @@ -23,11 +26,14 @@ START_TEST (elm_code_file_load_lines) { char *path = "elm_code/tests/testfile.txt"; Elm_Code_File *file; + Elm_Code *code; - file = elm_code_file_open(path); + code = elm_code_create(); + file = elm_code_file_open(code, path); ck_assert_uint_eq(4, elm_code_file_lines_get(file)); elm_code_file_close(file); + elm_code_free(code); } END_TEST @@ -35,11 +41,14 @@ START_TEST (elm_code_file_load_blank_lines) { char *path = "elm_code/tests/testfile-withblanks.txt"; Elm_Code_File *file; + Elm_Code *code; - file = elm_code_file_open(path); + code = elm_code_create(); + file = elm_code_file_open(code, path); ck_assert_uint_eq(8, elm_code_file_lines_get(file)); elm_code_file_close(file); + elm_code_free(code); } END_TEST @@ -47,12 +56,15 @@ START_TEST (elm_code_file_load_content) { char *path = "elm_code/tests/testfile.txt"; Elm_Code_File *file; + Elm_Code *code; - file = elm_code_file_open(path); + code = elm_code_create(); + file = elm_code_file_open(code, path); ck_assert_str_eq("line2", elm_code_file_line_content_get(file, 2)); ck_assert_str_eq("another line", elm_code_file_line_content_get(file, 4)); elm_code_file_close(file); + elm_code_free(code); } END_TEST diff --git a/elm_code/tests/elm_code_file_test_memory.c b/elm_code/tests/elm_code_file_test_memory.c index 21d2ce5..b359868 100644 --- a/elm_code/tests/elm_code_file_test_memory.c +++ b/elm_code/tests/elm_code_file_test_memory.c @@ -7,14 +7,16 @@ START_TEST (elm_code_file_memory_lines) { Elm_Code_File *file; + Elm_Code *code; - file = elm_code_file_new(); + code = elm_code_create(); + file = elm_code_file_new(code); ck_assert_uint_eq(0, elm_code_file_lines_get(file)); elm_code_file_line_append(file, "a line"); ck_assert_uint_eq(1, elm_code_file_lines_get(file)); - elm_code_file_free(file); + elm_code_free(code); } END_TEST @@ -22,15 +24,17 @@ START_TEST (elm_code_file_memory_tokens) { Elm_Code_File *file; Elm_Code_Line *line; + Elm_Code *code; - file = elm_code_file_new(); + code = elm_code_create(); + file = elm_code_file_new(code); elm_code_file_line_append(file, "a line"); elm_code_file_line_token_add(file, 1, 2, 5, ELM_CODE_TOKEN_TYPE_COMMENT); line = elm_code_file_line_get(file, 1); ck_assert_uint_eq(1, eina_list_count(line->tokens)); - elm_code_file_free(file); + elm_code_free(code); } END_TEST diff --git a/elm_code/tests/elm_code_suite.c b/elm_code/tests/elm_code_suite.c index 1d9763b..e2250cd 100644 --- a/elm_code/tests/elm_code_suite.c +++ b/elm_code/tests/elm_code_suite.c @@ -15,8 +15,9 @@ static const struct { } tests[] = { { "file_load", elm_code_file_test_load }, { "file_memory", elm_code_file_test_memory }, - { "widget", elm_code_test_widget }, + { "parse", elm_code_test_parse }, { "basic", elm_code_test_basic }, + { "widget", elm_code_test_widget }, }; START_TEST(elm_code_initialization) diff --git a/elm_code/tests/elm_code_suite.h b/elm_code/tests/elm_code_suite.h index bc2cc89..58d6317 100644 --- a/elm_code/tests/elm_code_suite.h +++ b/elm_code/tests/elm_code_suite.h @@ -7,7 +7,8 @@ void elm_code_file_test_load(TCase *tc); void elm_code_file_test_memory(TCase *tc); -void elm_code_test_widget(TCase *tc); void elm_code_test_basic(TCase *tc); +void elm_code_test_parse(TCase *tc); +void elm_code_test_widget(TCase *tc); #endif /* _EDLM_CODE_SUITE_H */ diff --git a/elm_code/tests/elm_code_test_basic.c b/elm_code/tests/elm_code_test_basic.c index f127cfb..81a34bb 100644 --- a/elm_code/tests/elm_code_test_basic.c +++ b/elm_code/tests/elm_code_test_basic.c @@ -7,11 +7,10 @@ START_TEST (elm_code_create_test) { char *path = "elm_code/tests/testfile.txt"; - Elm_Code_File *file; Elm_Code *code; - file = elm_code_file_open(path); - code = elm_code_create(file); + code = elm_code_create(); + elm_code_file_open(code, path); ck_assert(code); elm_code_free(code); diff --git a/elm_code/tests/elm_code_test_parse.c b/elm_code/tests/elm_code_test_parse.c new file mode 100644 index 0000000..3c4868e --- /dev/null +++ b/elm_code/tests/elm_code_test_parse.c @@ -0,0 +1,68 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "elm_code_suite.h" +#include "elm_code_parse.h" + +static int line_calls, file_calls; + +static void _parser_line_callback(Elm_Code_Line *line EINA_UNUSED) +{ + line_calls++; +} + +static void _parser_file_callback(Elm_Code_File *file EINA_UNUSED) +{ + file_calls++; +} + +START_TEST (elm_code_parse_hook_memory_test) +{ + Elm_Code *code; + Elm_Code_File *file; + + line_calls = 0; + file_calls = 0; + + code = elm_code_create(); + file = elm_code_file_new(code); + + elm_code_parser_add(code, _parser_line_callback, _parser_file_callback); + elm_code_file_line_append(file, "some \"test content\" for parsing"); + + ck_assert_int_eq(1, line_calls); + ck_assert_int_eq(0, file_calls); + + elm_code_free(code); +} +END_TEST + +START_TEST (elm_code_parse_hook_file_test) +{ + Elm_Code *code; + Elm_Code_File *file; + char *path = "elm_code/tests/testfile.txt"; + + line_calls = 0; + file_calls = 0; + + code = elm_code_create(); + + elm_code_parser_add(code, _parser_line_callback, _parser_file_callback); + file = elm_code_file_open(code, path); + + ck_assert_int_eq(4, line_calls); + ck_assert_int_eq(1, file_calls); + + elm_code_file_close(file); + elm_code_free(code); +} +END_TEST + +void elm_code_test_parse(TCase *tc) +{ + tcase_add_test(tc, elm_code_parse_hook_memory_test); + tcase_add_test(tc, elm_code_parse_hook_file_test); +} + diff --git a/elm_code/tests/elm_code_test_widget.c b/elm_code/tests/elm_code_test_widget.c index 77bedd1..27b867e 100644 --- a/elm_code/tests/elm_code_test_widget.c +++ b/elm_code/tests/elm_code_test_widget.c @@ -13,11 +13,13 @@ START_TEST (elm_code_widget_token_render_simple_test) { Elm_Code_File *file; Elm_Code_Line *line; + Elm_Code *code; int length; Evas_Textgrid_Cell cells[25]; - file = elm_code_file_new(); + code = elm_code_create(); + file = elm_code_file_new(code); elm_code_file_line_append(file, "some \"test content\", 45"); line = elm_code_file_line_get(file, 1); length = strlen(line->content); @@ -33,7 +35,7 @@ START_TEST (elm_code_widget_token_render_simple_test) _assert_cell_type(cells[19], ELM_CODE_TOKEN_TYPE_DEFAULT); _assert_cell_type(cells[22], ELM_CODE_TOKEN_TYPE_COMMENT); - elm_code_file_free(file); + elm_code_free(code); } END_TEST diff --git a/src/bin/edi_logpanel.c b/src/bin/edi_logpanel.c index ec4ae74..c065fb5 100644 --- a/src/bin/edi_logpanel.c +++ b/src/bin/edi_logpanel.c @@ -42,7 +42,8 @@ void edi_logpanel_add(Evas_Object *parent) Evas_Object *widget; Elm_Code *code; - code = elm_code_create(elm_code_file_new()); + code = elm_code_create(); + elm_code_file_new(code); widget = elm_code_widget_add(parent, code); evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL);