From a78a0301e7a77b78b354a4a7aa2ad1d1355d33fa Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Fri, 17 Oct 2014 21:36:03 +0100 Subject: [PATCH 01/36] Base addition of elm_code area within the edi codebase, including an empty test to verify it's working --- Makefile.am | 4 +- configure.ac | 3 + elm_code/Makefile.am | 4 + elm_code/lib/Elm_Code.h | 95 ++++++++++++++++++++++ elm_code/lib/Makefile.am | 19 +++++ elm_code/lib/elm_code.c | 58 +++++++++++++ elm_code/lib/elm_code_private.h | 27 ++++++ elm_code/tests/Makefile.am | 21 +++++ elm_code/tests/elm_code_suite.c | 122 ++++++++++++++++++++++++++++ elm_code/tests/elm_code_suite.h | 10 +++ elm_code/tests/elm_code_test_load.c | 17 ++++ 11 files changed, 378 insertions(+), 2 deletions(-) create mode 100644 elm_code/Makefile.am create mode 100644 elm_code/lib/Elm_Code.h create mode 100644 elm_code/lib/Makefile.am create mode 100644 elm_code/lib/elm_code.c create mode 100644 elm_code/lib/elm_code_private.h create mode 100644 elm_code/tests/Makefile.am create mode 100644 elm_code/tests/elm_code_suite.c create mode 100644 elm_code/tests/elm_code_suite.h create mode 100644 elm_code/tests/elm_code_test_load.c diff --git a/Makefile.am b/Makefile.am index 822c51a..3e59bc3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -29,7 +29,7 @@ MAINTAINERCLEANFILES = \ $(PACKAGE_TARNAME)-$(PACKAGE_VERSION).tar.gz \ $(PACKAGE_TARNAME)-$(PACKAGE_VERSION).tar.bz2 -SUBDIRS = data doc packaging po src +SUBDIRS = data doc packaging po elm_code src ACLOCAL_AMFLAGS = -I m4 @@ -73,7 +73,7 @@ endif if EFL_HAVE_TESTS -TESTS = src/tests/edi_suite +TESTS = elm_code/tests/elm_code_suite src/tests/edi_suite lcov-check: if EFL_HAVE_LCOV diff --git a/configure.ac b/configure.ac index b3cf135..5ef2c99 100644 --- a/configure.ac +++ b/configure.ac @@ -101,6 +101,9 @@ src/Makefile src/bin/Makefile src/lib/Makefile src/tests/Makefile +elm_code/Makefile +elm_code/lib/Makefile +elm_code/tests/Makefile doc/edi.1 ]) AC_OUTPUT diff --git a/elm_code/Makefile.am b/elm_code/Makefile.am new file mode 100644 index 0000000..d01d7e3 --- /dev/null +++ b/elm_code/Makefile.am @@ -0,0 +1,4 @@ +MAINTAINERCLEANFILES = Makefile.in + +SUBDIRS = lib tests + diff --git a/elm_code/lib/Elm_Code.h b/elm_code/lib/Elm_Code.h new file mode 100644 index 0000000..13f6369 --- /dev/null +++ b/elm_code/lib/Elm_Code.h @@ -0,0 +1,95 @@ +#ifndef ELM_CODE_H_ +# define ELM_CODE_H_ + +#include + +#ifdef EAPI +# undef EAPI +#endif + +#ifdef _WIN32 +# ifdef EFL_ELM_CODE_BUILD +# ifdef DLL_EXPORT +# define EAPI __declspec(dllexport) +# else +# define EAPI +# endif /* ! DLL_EXPORT */ +# else +# define EAPI __declspec(dllimport) +# endif /* ! EFL_ELM_CODE_BUILD */ +#else +# ifdef __GNUC__ +# if __GNUC__ >= 4 +# define EAPI __attribute__ ((visibility("default"))) +# else +# define EAPI +# endif +# else +# define EAPI +# endif +#endif /* ! _WIN32 */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file + * @brief These routines are used for interacting with files using Elm Code. + */ + +/** + * @brief Init / shutdown functions. + * @defgroup Init Init / Shutdown + * + * @{ + * + * Functions of obligatory usage, handling proper initialization + * and shutdown routines. + * + * Before the usage of any other function, Elm Code should be properly + * initialized with @ref elm_code_init() and the last call to Elm Code's + * functions should be @ref elm_code_shutdown(), so everything will + * be correctly freed. + * + * Elm Code logs everything with Eina Log, using the "elm_code" log domain. + * + */ + +/** + * Initialize Elm Code. + * + * Initializes Elm Code, its dependencies and modules. Should be the first + * function of Elm Code to be called. + * + * @return The init counter value. + * + * @see elm_code_shutdown(). + * + * @ingroup Init + */ +EAPI int elm_code_init(void); + +/** + * Shutdown Elm Code + * + * Shutdown Elm Code. If init count reaches 0, all the internal structures will + * be freed. Any Elm Code library call after this point will leads to an error. + * + * @return Elm Code's init counter value. + * + * @see elm_code_init(). + * + * @ingroup Init + */ +EAPI int elm_code_shutdown(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ELM_CODE_H_ */ diff --git a/elm_code/lib/Makefile.am b/elm_code/lib/Makefile.am new file mode 100644 index 0000000..468b75a --- /dev/null +++ b/elm_code/lib/Makefile.am @@ -0,0 +1,19 @@ +MAINTAINERCLEANFILES = Makefile.in + +AM_CPPFLAGS = \ +-I$(top_srcdir)/elm_code/lib \ +-I$(top_builddir)/elm_code/lib \ +-DPACKAGE_LIB_DIR=\"$(libdir)\" \ +-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ +@EFL_CFLAGS@ \ +-DEFL_EFL_BUILD + +lib_LTLIBRARIES = libelm_code.la + +includes_HEADERS = Elm_Code.h +includesdir = $(includedir)/edi-@VMAJ@ + +libelm_code_la_SOURCES = \ +elm_code.c +libelm_code_la_LIBADD = @EFL_LIBS@ -lm +libelm_code_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@ diff --git a/elm_code/lib/elm_code.c b/elm_code/lib/elm_code.c new file mode 100644 index 0000000..0532ce6 --- /dev/null +++ b/elm_code/lib/elm_code.c @@ -0,0 +1,58 @@ +#ifdef HAVE_CONFIG +# include "config.h" +#endif + +#include "Elm_Code.h" + +#include "elm_code_private.h" + +static int _elm_code_init = 0; +int _elm_code_lib_log_dom = -1; + +EAPI int +elm_code_init(void) +{ + _elm_code_init++; + if (_elm_code_init > 1) return _elm_code_init; + + eina_init(); + + _elm_code_lib_log_dom = eina_log_domain_register("elm_code", EINA_COLOR_CYAN); + if (_elm_code_lib_log_dom < 0) + { + EINA_LOG_ERR("Elm Code can not create its log domain."); + goto shutdown_eina; + } + + // Put here your initialization logic of your library + + eina_log_timing(_elm_code_lib_log_dom, EINA_LOG_STATE_STOP, EINA_LOG_STATE_INIT); + + return _elm_code_init; + + shutdown_eina: + eina_shutdown(); + _elm_code_init--; + + return _elm_code_init; +} + +EAPI int +elm_code_shutdown(void) +{ + _elm_code_init--; + if (_elm_code_init != 0) return _elm_code_init; + + eina_log_timing(_elm_code_lib_log_dom, + EINA_LOG_STATE_START, + EINA_LOG_STATE_SHUTDOWN); + + // Put here your shutdown logic + + eina_log_domain_unregister(_elm_code_lib_log_dom); + _elm_code_lib_log_dom = -1; + + eina_shutdown(); + + return _elm_code_init; +} diff --git a/elm_code/lib/elm_code_private.h b/elm_code/lib/elm_code_private.h new file mode 100644 index 0000000..d1ff328 --- /dev/null +++ b/elm_code/lib/elm_code_private.h @@ -0,0 +1,27 @@ +#ifndef ELM_CODE_PRIVATE_H +# define ELM_CODE_PRIVATE_H + +extern int _elm_code_lib_log_dom; + +#ifdef ERR +# undef ERR +#endif +#define ERR(...) EINA_LOG_DOM_ERR(_elm_code_lib_log_dom, __VA_ARGS__) +#ifdef INF +# undef INF +#endif +#define INF(...) EINA_LOG_DOM_INFO(_elm_code_lib_log_dom, __VA_ARGS__) +#ifdef WRN +# undef WRN +#endif +#define WRN(...) EINA_LOG_DOM_WARN(_elm_code_lib_log_dom, __VA_ARGS__) +#ifdef CRIT +# undef CRIT +#endif +#define CRIT(...) EINA_LOG_DOM_CRIT(_elm_code_lib_log_dom, __VA_ARGS__) +#ifdef DBG +# undef DBG +#endif +#define DBG(...) EINA_LOG_DOM_DBG(_elm_code_lib_log_dom, __VA_ARGS__) + +#endif diff --git a/elm_code/tests/Makefile.am b/elm_code/tests/Makefile.am new file mode 100644 index 0000000..5652799 --- /dev/null +++ b/elm_code/tests/Makefile.am @@ -0,0 +1,21 @@ + +if EFL_HAVE_TESTS + +check_PROGRAMS = elm_code_suite + +elm_code_suite_SOURCES = \ +elm_code_test_load.c \ +elm_code_suite.c + +elm_code_suite_CPPFLAGS = -I$(top_builddir)/elm_code/lib/ \ +-DPACKAGE_TESTS_DIR=\"$(top_srcdir)/elm_code/tests/\" \ +-DPACKAGE_BUILD_DIR=\"`pwd`/$(top_builddir)/elm_code/tests/\" \ +@EFL_CFLAGS@ \ +@CHECK_CFLAGS@ + +elm_code_suite_LDADD = @CHECK_LIBS@ $(top_builddir)/elm_code/lib/libelm_code.la +elm_code_suite_DEPENDENCIES = $(top_builddir)/elm_code/lib/libelm_code.la + +endif + +EXTRA_DIST = elm_code_suite.h diff --git a/elm_code/tests/elm_code_suite.c b/elm_code/tests/elm_code_suite.c new file mode 100644 index 0000000..7b74ec2 --- /dev/null +++ b/elm_code/tests/elm_code_suite.c @@ -0,0 +1,122 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "Elm_Code.h" +#include "elm_code_suite.h" + +#define COPYRIGHT "Copyright © 2014 Andy Williams and various contributors (see AUTHORS)." + +static const struct { + const char *name; + void (*build)(TCase *tc); +} tests[] = { + { "load", elm_code_test_load }, +}; + +START_TEST(elm_code_initialization) +{ + fail_if(elm_code_init() != 1); + +// TODO add other init checks here + + fail_if(elm_code_shutdown() != 0); +} +END_TEST + +void +edi_test_basic(TCase *tc) +{ + tcase_add_test(tc, elm_code_initialization); +} + +static const Ecore_Getopt optdesc = { + "elm_code", + "%prog [options]", + PACKAGE_VERSION, + COPYRIGHT, + "BSD with advertisement clause", + "Elm Code", + 0, + { + ECORE_GETOPT_STORE_TRUE('l', "list", "list available tests"), + ECORE_GETOPT_STORE_STR('t', "test", "test to run"), + ECORE_GETOPT_LICENSE('L', "license"), + ECORE_GETOPT_COPYRIGHT('C', "copyright"), + ECORE_GETOPT_VERSION('V', "version"), + ECORE_GETOPT_HELP('h', "help"), + ECORE_GETOPT_SENTINEL + } +}; + +int +main(int argc EINA_UNUSED, char **argv EINA_UNUSED) +{ + Suite *s; + SRunner *sr; + TCase *tc = NULL; + char *test = NULL; + unsigned int i; + int failed_count = -1; + int args; + Eina_Bool quit_option = EINA_FALSE; + Eina_Bool list_option = EINA_FALSE; + + Ecore_Getopt_Value values[] = { + ECORE_GETOPT_VALUE_BOOL(list_option), + ECORE_GETOPT_VALUE_STR(test), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_NONE + }; + + eina_init(); + + args = ecore_getopt_parse(&optdesc, values, argc, argv); + if (args < 0) + { + EINA_LOG_CRIT("Could not parse arguments."); + goto end; + } + else if (quit_option) + { + goto end; + } + else if (list_option) + { + fprintf(stdout, "Available tests :\n"); + for (i = 0; i < sizeof (tests) / sizeof (tests[0]); i++) + fprintf(stdout, "\t%s\n", tests[i].name); + goto end; + } + + s = suite_create("Elm_Code"); + + for (i = 0; i < sizeof (tests) / sizeof (tests[0]); i++) + { + if (test && strcmp(tests[i].name, test)) + continue ; + + tc = tcase_create(tests[i].name); + tcase_set_timeout(tc, 0); + + tests[i].build(tc); + suite_add_tcase(s, tc); + } + + sr = srunner_create(s); + srunner_set_xml(sr, PACKAGE_BUILD_DIR "/check-results.xml"); + + srunner_run_all(sr, CK_ENV); + failed_count = srunner_ntests_failed(sr); + srunner_free(sr); + + end: + eina_shutdown(); + + return (failed_count == 0) ? 0 : 255; +} diff --git a/elm_code/tests/elm_code_suite.h b/elm_code/tests/elm_code_suite.h new file mode 100644 index 0000000..2cdf523 --- /dev/null +++ b/elm_code/tests/elm_code_suite.h @@ -0,0 +1,10 @@ +#ifndef _ELM_CODE_SUITE_H +#define _ELM_CODE_SUITE_H + +#include + +#include + +void elm_code_test_load(TCase *tc); + +#endif /* _EDLM_CODE_SUITE_H */ diff --git a/elm_code/tests/elm_code_test_load.c b/elm_code/tests/elm_code_test_load.c new file mode 100644 index 0000000..807e06e --- /dev/null +++ b/elm_code/tests/elm_code_test_load.c @@ -0,0 +1,17 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "elm_code_suite.h" + +START_TEST (elm_code_load) +{ + ck_assert(1); +} +END_TEST + +void elm_code_test_load(TCase *tc) +{ + tcase_add_test(tc, elm_code_load); +} + From b38f986767722242dccbac29117a4d23eea72773 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Fri, 17 Oct 2014 23:36:07 +0100 Subject: [PATCH 02/36] A pretty slim test of file loading and initial path apis --- elm_code/lib/Elm_Code.h | 24 ++++++++++++++++++++++++ elm_code/lib/elm_code.c | 28 ++++++++++++++++++++++++++++ elm_code/tests/elm_code_test_load.c | 11 ++++++++++- elm_code/tests/testfile.txt | 5 +++++ 4 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 elm_code/tests/testfile.txt diff --git a/elm_code/lib/Elm_Code.h b/elm_code/lib/Elm_Code.h index 13f6369..f560bbc 100644 --- a/elm_code/lib/Elm_Code.h +++ b/elm_code/lib/Elm_Code.h @@ -3,6 +3,8 @@ #include +#include + #ifdef EAPI # undef EAPI #endif @@ -38,6 +40,20 @@ extern "C" { * @brief These routines are used for interacting with files using Elm Code. */ +typedef struct _Elm_Code_Line +{ + const char *content; + const char *modified; + +} Elm_Code_Line; + +typedef struct _Elm_Code_File +{ + Elm_Code_Line *lines; + Eina_File *file; + +} Elm_Code_File; + /** * @brief Init / shutdown functions. * @defgroup Init Init / Shutdown @@ -84,6 +100,14 @@ EAPI int elm_code_init(void); */ EAPI int elm_code_shutdown(void); +EAPI Elm_Code_File *elm_code_open(const char *path); + +EAPI void elm_code_close(Elm_Code_File *file); + +EAPI const char *elm_code_filename_get(Elm_Code_File *file); + +EAPI const char *elm_code_path_get(Elm_Code_File *file); + /** * @} */ diff --git a/elm_code/lib/elm_code.c b/elm_code/lib/elm_code.c index 0532ce6..44b251a 100644 --- a/elm_code/lib/elm_code.c +++ b/elm_code/lib/elm_code.c @@ -56,3 +56,31 @@ elm_code_shutdown(void) return _elm_code_init; } + +EAPI Elm_Code_File *elm_code_open(const char *path) +{ + Elm_Code_File *ret; + Eina_File *file; + + file = eina_file_open(path, EINA_FALSE); + ret = calloc(1, sizeof(ret)); + ret->file = file; + + return ret; +} + +EAPI void elm_code_close(Elm_Code_File *file) +{ + eina_file_close(file->file); + free(file); +} + +EAPI const char *elm_code_filename_get(Elm_Code_File *file) +{ + return basename(eina_file_filename_get(file->file)); +} + +EAPI const char *elm_code_path_get(Elm_Code_File *file) +{ + return eina_file_filename_get(file->file); +} \ No newline at end of file diff --git a/elm_code/tests/elm_code_test_load.c b/elm_code/tests/elm_code_test_load.c index 807e06e..926b2aa 100644 --- a/elm_code/tests/elm_code_test_load.c +++ b/elm_code/tests/elm_code_test_load.c @@ -6,7 +6,16 @@ START_TEST (elm_code_load) { - ck_assert(1); + char *path = "elm_code/tests/testfile.txt"; + char real[EINA_PATH_MAX]; + Elm_Code_File *file; + + file = elm_code_open(path); + realpath(path, real); + + ck_assert_str_eq(basename(path), elm_code_filename_get(file)); + ck_assert_str_eq(real, elm_code_path_get(file)); + elm_code_close(file); } END_TEST diff --git a/elm_code/tests/testfile.txt b/elm_code/tests/testfile.txt new file mode 100644 index 0000000..246d68e --- /dev/null +++ b/elm_code/tests/testfile.txt @@ -0,0 +1,5 @@ +line 1 +line2 + +another line +5 From 676018f60d68524bcbc2ebef2f3d98ee160fb657 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Fri, 17 Oct 2014 23:43:15 +0100 Subject: [PATCH 03/36] Disable a broken test for now - we're focussing on testing elm_code at the moment --- src/tests/Makefile.am | 1 - src/tests/edi_suite.c | 1 - src/tests/{edi_test_console.c => edi_test_console.c-old} | 0 3 files changed, 2 deletions(-) rename src/tests/{edi_test_console.c => edi_test_console.c-old} (100%) diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index d18854e..2b2a7f2 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -5,7 +5,6 @@ check_PROGRAMS = edi_suite edi_suite_SOURCES = \ edi_test_path.c \ -edi_test_console.c \ edi_suite.c edi_suite_CPPFLAGS = -I$(top_builddir)/src/lib/ -I$(top_builddir)/src/bin/ \ diff --git a/src/tests/edi_suite.c b/src/tests/edi_suite.c index b168ba7..f57bf16 100644 --- a/src/tests/edi_suite.c +++ b/src/tests/edi_suite.c @@ -14,7 +14,6 @@ static const struct { void (*build)(TCase *tc); } tests[] = { { "basic", edi_test_basic }, - { "console", edi_test_console }, { "path", edi_test_path } }; diff --git a/src/tests/edi_test_console.c b/src/tests/edi_test_console.c-old similarity index 100% rename from src/tests/edi_test_console.c rename to src/tests/edi_test_console.c-old From 69feac6ced5b27ac5bcf42ed086fbf0557dc3d89 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Fri, 17 Oct 2014 23:46:42 +0100 Subject: [PATCH 04/36] updated gitignore --- .gitignore | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 32da06d..51a23b6 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,6 @@ /src/bin/edi /src/bin/edi_build -/src/tests/edi_suite /data/desktop/edi.desktop /doc/edi.1 edi-*.tar.?z* @@ -60,6 +59,12 @@ po/remove-potcdate.sin po/stamp-po /coverage/ +/src/tests/edi_suite /src/tests/edi_suite.* /src/tests/test-suite.log /src/tests/check-results.xml + +/elm_code/tests/elm_code_suite +/elm_code/tests/elm_code_suite.* +/elm_code/tests/test-suite.log +/elm_code/tests/check-results.xml From 0bb5201e3c29c7f871b2872f2343dc9c1c71cd08 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sun, 19 Oct 2014 22:29:44 +0100 Subject: [PATCH 05/36] Load lines sequentially and insert to a structure for reference --- elm_code/lib/Elm_Code.h | 9 +++++--- elm_code/lib/elm_code.c | 33 +++++++++++++++++++++++++++-- elm_code/tests/elm_code_test_load.c | 13 ++++++++++++ elm_code/tests/testfile.txt | 3 +-- 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/elm_code/lib/Elm_Code.h b/elm_code/lib/Elm_Code.h index f560bbc..090a900 100644 --- a/elm_code/lib/Elm_Code.h +++ b/elm_code/lib/Elm_Code.h @@ -42,15 +42,16 @@ extern "C" { typedef struct _Elm_Code_Line { - const char *content; - const char *modified; + Eina_File_Line content; + Eina_File_Line modified; } Elm_Code_Line; typedef struct _Elm_Code_File { - Elm_Code_Line *lines; + Eina_List *lines; Eina_File *file; + void *map; } Elm_Code_File; @@ -108,6 +109,8 @@ EAPI const char *elm_code_filename_get(Elm_Code_File *file); EAPI const char *elm_code_path_get(Elm_Code_File *file); +EAPI int elm_code_lines_get(Elm_Code_File *file); + /** * @} */ diff --git a/elm_code/lib/elm_code.c b/elm_code/lib/elm_code.c index 44b251a..af2b6de 100644 --- a/elm_code/lib/elm_code.c +++ b/elm_code/lib/elm_code.c @@ -61,16 +61,40 @@ EAPI Elm_Code_File *elm_code_open(const char *path) { Elm_Code_File *ret; Eina_File *file; + Eina_File_Line *line; + Eina_Iterator *it; + void *map; file = eina_file_open(path, EINA_FALSE); - ret = calloc(1, sizeof(ret)); + map = eina_file_map_all(file, EINA_FILE_WILLNEED); + ret = calloc(1, sizeof(Elm_Code_File)); ret->file = file; + ret->map = map; + + it = eina_file_map_lines(file); + EINA_ITERATOR_FOREACH(it, line) + { + Elm_Code_Line *ecl; + + ecl = calloc(1, sizeof(Elm_Code_Line)); + if (!ecl) continue; + + ecl->content = *line; + ret->lines = eina_list_append(ret->lines, ecl); + } + eina_iterator_free(it); return ret; } EAPI void elm_code_close(Elm_Code_File *file) { + Elm_Code_Line *l; + + EINA_LIST_FREE(file->lines, l) + free(l); + + eina_file_map_free(file->file, file->map); eina_file_close(file->file); free(file); } @@ -83,4 +107,9 @@ EAPI const char *elm_code_filename_get(Elm_Code_File *file) EAPI const char *elm_code_path_get(Elm_Code_File *file) { return eina_file_filename_get(file->file); -} \ No newline at end of file +} + +EAPI int elm_code_lines_get(Elm_Code_File *file) +{ + return eina_list_count(file->lines); +} diff --git a/elm_code/tests/elm_code_test_load.c b/elm_code/tests/elm_code_test_load.c index 926b2aa..13610db 100644 --- a/elm_code/tests/elm_code_test_load.c +++ b/elm_code/tests/elm_code_test_load.c @@ -19,8 +19,21 @@ START_TEST (elm_code_load) } END_TEST +START_TEST (elm_code_load_lines) +{ + char *path = "elm_code/tests/testfile.txt"; + Elm_Code_File *file; + + file = elm_code_open(path); + + ck_assert(4 == elm_code_lines_get(file)); + elm_code_close(file); +} +END_TEST + void elm_code_test_load(TCase *tc) { tcase_add_test(tc, elm_code_load); + tcase_add_test(tc, elm_code_load_lines); } diff --git a/elm_code/tests/testfile.txt b/elm_code/tests/testfile.txt index 246d68e..8fd6a8b 100644 --- a/elm_code/tests/testfile.txt +++ b/elm_code/tests/testfile.txt @@ -1,5 +1,4 @@ line 1 line2 - +a third another line -5 From 6cf6df3886fef15f32cab2cee7634ad11213eee4 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sun, 19 Oct 2014 22:33:49 +0100 Subject: [PATCH 06/36] Load the content and verify from our test files. Includes an eina_file_map_lines workaround for blank lines --- elm_code/lib/Elm_Code.h | 7 ++-- elm_code/lib/elm_code.c | 49 +++++++++++++++++++++----- elm_code/tests/elm_code_test_load.c | 27 ++++++++++++++ elm_code/tests/testfile-withblanks.txt | 8 +++++ 4 files changed, 80 insertions(+), 11 deletions(-) create mode 100644 elm_code/tests/testfile-withblanks.txt diff --git a/elm_code/lib/Elm_Code.h b/elm_code/lib/Elm_Code.h index 090a900..e03aa26 100644 --- a/elm_code/lib/Elm_Code.h +++ b/elm_code/lib/Elm_Code.h @@ -42,8 +42,8 @@ extern "C" { typedef struct _Elm_Code_Line { - Eina_File_Line content; - Eina_File_Line modified; + char *content; + unsigned int number; } Elm_Code_Line; @@ -51,7 +51,6 @@ typedef struct _Elm_Code_File { Eina_List *lines; Eina_File *file; - void *map; } Elm_Code_File; @@ -111,6 +110,8 @@ EAPI const char *elm_code_path_get(Elm_Code_File *file); EAPI int elm_code_lines_get(Elm_Code_File *file); +EAPI char *elm_code_line_content_get(Elm_Code_File *file, int line); + /** * @} */ diff --git a/elm_code/lib/elm_code.c b/elm_code/lib/elm_code.c index af2b6de..66cb04c 100644 --- a/elm_code/lib/elm_code.c +++ b/elm_code/lib/elm_code.c @@ -57,29 +57,51 @@ elm_code_shutdown(void) return _elm_code_init; } +static Elm_Code_Line *_elm_code_blank_create(int line) +{ + Elm_Code_Line *ecl; + + ecl = calloc(1, sizeof(Elm_Code_Line)); + if (!ecl) return NULL; + + ecl->number = line; + return ecl; +} + EAPI Elm_Code_File *elm_code_open(const char *path) { Elm_Code_File *ret; Eina_File *file; Eina_File_Line *line; Eina_Iterator *it; - void *map; + unsigned int lastindex; file = eina_file_open(path, EINA_FALSE); - map = eina_file_map_all(file, EINA_FILE_WILLNEED); ret = calloc(1, sizeof(Elm_Code_File)); ret->file = file; - ret->map = map; + lastindex = 1; it = eina_file_map_lines(file); EINA_ITERATOR_FOREACH(it, line) { Elm_Code_Line *ecl; - ecl = calloc(1, sizeof(Elm_Code_Line)); + /* Working around the issue that eina_file_map_lines does not trigger an item for empty lines */ + while (lastindex < line->index - 1) + { + ecl = _elm_code_blank_create(++lastindex); + if (!ecl) continue; + + ret->lines = eina_list_append(ret->lines, ecl); + } + + ecl = _elm_code_blank_create(lastindex = line->index); if (!ecl) continue; - ecl->content = *line; + ecl->content = malloc(sizeof(char) * (line->length + 1)); + strncpy(ecl->content, line->start, line->length); + ecl->content[line->length] = 0; + ret->lines = eina_list_append(ret->lines, ecl); } eina_iterator_free(it); @@ -92,16 +114,19 @@ EAPI void elm_code_close(Elm_Code_File *file) Elm_Code_Line *l; EINA_LIST_FREE(file->lines, l) - free(l); + { + if (l->content) + free(l->content); + free(l); + } - eina_file_map_free(file->file, file->map); eina_file_close(file->file); free(file); } EAPI const char *elm_code_filename_get(Elm_Code_File *file) { - return basename(eina_file_filename_get(file->file)); + return basename((char *)eina_file_filename_get(file->file)); } EAPI const char *elm_code_path_get(Elm_Code_File *file) @@ -113,3 +138,11 @@ EAPI int elm_code_lines_get(Elm_Code_File *file) { return eina_list_count(file->lines); } + +EAPI char *elm_code_line_content_get(Elm_Code_File *file, int number) +{ + Elm_Code_Line *line; + + line = eina_list_nth(file->lines, number); + return line->content; +} diff --git a/elm_code/tests/elm_code_test_load.c b/elm_code/tests/elm_code_test_load.c index 13610db..2431603 100644 --- a/elm_code/tests/elm_code_test_load.c +++ b/elm_code/tests/elm_code_test_load.c @@ -31,9 +31,36 @@ START_TEST (elm_code_load_lines) } END_TEST +START_TEST (elm_code_load_blank_lines) +{ + char *path = "elm_code/tests/testfile-withblanks.txt"; + Elm_Code_File *file; + + file = elm_code_open(path); + + ck_assert(8 == elm_code_lines_get(file)); + elm_code_close(file); +} +END_TEST + +START_TEST (elm_code_load_content) +{ + char *path = "elm_code/tests/testfile.txt"; + Elm_Code_File *file; + + file = elm_code_open(path); + + ck_assert_str_eq("line2", elm_code_line_content_get(file, 2 - 1)); + ck_assert_str_eq("another line", elm_code_line_content_get(file, 4 - 1)); + elm_code_close(file); +} +END_TEST + void elm_code_test_load(TCase *tc) { tcase_add_test(tc, elm_code_load); tcase_add_test(tc, elm_code_load_lines); + tcase_add_test(tc, elm_code_load_blank_lines); + tcase_add_test(tc, elm_code_load_content); } diff --git a/elm_code/tests/testfile-withblanks.txt b/elm_code/tests/testfile-withblanks.txt new file mode 100644 index 0000000..0f2ead3 --- /dev/null +++ b/elm_code/tests/testfile-withblanks.txt @@ -0,0 +1,8 @@ +line 1 +line2 + +another link + + +double blank +8 From 9838f4b35c25ca171c3d3806d190a8c0535ded38 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Mon, 20 Oct 2014 23:20:14 +0100 Subject: [PATCH 07/36] Using the +/- format application to remove bold etc where used. This requires a patch from herdsman to evas to work effectively --- src/bin/editor/edi_editor.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/bin/editor/edi_editor.c b/src/bin/editor/edi_editor.c index 61736a9..1e3139e 100644 --- a/src/bin/editor/edi_editor.c +++ b/src/bin/editor/edi_editor.c @@ -32,7 +32,7 @@ static Edi_Color EDI_COLOR_CLASS = "+ color=#72AAD4 font_weight=Bold"; static Edi_Color EDI_COLOR_FUNCTION = "+ color=#72AAD4 font_weight=Bold"; static Edi_Color EDI_COLOR_PARAM = "+ color=#ffffff"; static Edi_Color EDI_COLOR_KEYWORD = "+ color=#ff9900 font_weight=Bold"; -static Edi_Color EDI_COLOR_PREPROCESSOR = "+ color=#00B000 font_weight=Bold"; +static Edi_Color EDI_COLOR_PREPROCESSOR = "+ color=#00B000"; static Edi_Color EDI_COLOR_BACKGROUND = "+ backing_color=#000000"; static Edi_Color EDI_COLOR_SEVIRITY_IGNORED = "+ backing_color=#000000"; @@ -280,13 +280,19 @@ _edi_editor_statusbar_add(Evas_Object *panel, Edi_Editor *editor, Edi_Mainview_I static void _edi_range_color_set(Edi_Editor *editor, Edi_Range range, Edi_Color color) { + char *format; + format = strdup(color); + evas_textblock_cursor_line_set(_format_cursor, range.start.line - 1); evas_textblock_cursor_pos_set(_format_cursor, evas_textblock_cursor_pos_get(_format_cursor) + range.start.col - 1); - evas_textblock_cursor_format_prepend(_format_cursor, color); + evas_textblock_cursor_format_prepend(_format_cursor, format); + format[0] = '-'; evas_textblock_cursor_line_set(_format_cursor, range.end.line - 1); evas_textblock_cursor_pos_set(_format_cursor, evas_textblock_cursor_pos_get(_format_cursor) + range.end.col - 1); - evas_textblock_cursor_format_append(_format_cursor, EDI_COLOR_FOREGROUND); + evas_textblock_cursor_format_append(_format_cursor, format); + + free(format); } static void From 4eaf564f018e6c49ca2a68ec7b16e1e1a31f05af Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Tue, 21 Oct 2014 14:26:01 +0100 Subject: [PATCH 08/36] Use the recommended formatting for colour, avoid font weight right now as it doesn't stack properly --- src/bin/editor/edi_editor.c | 40 ++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/src/bin/editor/edi_editor.c b/src/bin/editor/edi_editor.c index 1e3139e..19e3016 100644 --- a/src/bin/editor/edi_editor.c +++ b/src/bin/editor/edi_editor.c @@ -22,22 +22,22 @@ #define Edi_Color const char * -static Edi_Color EDI_COLOR_FOREGROUND = "+ color=#ffffff"; -static Edi_Color EDI_COLOR_COMMENT = "+ color=#3399ff"; -static Edi_Color EDI_COLOR_STRING = "+ color=#ff3a35"; -static Edi_Color EDI_COLOR_NUMBER = "+ color=#D4D42A font_weight=Bold"; -static Edi_Color EDI_COLOR_BRACE = "+ color=#656565"; -static Edi_Color EDI_COLOR_TYPE = "+ color=#3399ff"; -static Edi_Color EDI_COLOR_CLASS = "+ color=#72AAD4 font_weight=Bold"; -static Edi_Color EDI_COLOR_FUNCTION = "+ color=#72AAD4 font_weight=Bold"; -static Edi_Color EDI_COLOR_PARAM = "+ color=#ffffff"; -static Edi_Color EDI_COLOR_KEYWORD = "+ color=#ff9900 font_weight=Bold"; -static Edi_Color EDI_COLOR_PREPROCESSOR = "+ color=#00B000"; +static Edi_Color EDI_COLOR_FOREGROUND = ""; +static Edi_Color EDI_COLOR_COMMENT = ""; +static Edi_Color EDI_COLOR_STRING = ""; +static Edi_Color EDI_COLOR_NUMBER = "";// font_weight=Bold"; +static Edi_Color EDI_COLOR_BRACE = ""; +static Edi_Color EDI_COLOR_TYPE = ""; +static Edi_Color EDI_COLOR_CLASS = "";// font_weight=Bold"; +static Edi_Color EDI_COLOR_FUNCTION = "";// font_weight=Bold"; +static Edi_Color EDI_COLOR_PARAM = ""; +static Edi_Color EDI_COLOR_KEYWORD = "";// font_weight=Bold"; +static Edi_Color EDI_COLOR_PREPROCESSOR = ""; -static Edi_Color EDI_COLOR_BACKGROUND = "+ backing_color=#000000"; -static Edi_Color EDI_COLOR_SEVIRITY_IGNORED = "+ backing_color=#000000"; -static Edi_Color EDI_COLOR_SEVIRITY_NOTE = "+ backing_color=#ff9900"; -static Edi_Color EDI_COLOR_SEVIRITY_WARNING = "+ backing_color=#ff9900"; +static Edi_Color EDI_COLOR_BACKGROUND = "+"; +static Edi_Color EDI_COLOR_SEVIRITY_IGNORED = ""; +static Edi_Color EDI_COLOR_SEVIRITY_NOTE = ""; +static Edi_Color EDI_COLOR_SEVIRITY_WARNING = ""; typedef struct { @@ -280,19 +280,13 @@ _edi_editor_statusbar_add(Evas_Object *panel, Edi_Editor *editor, Edi_Mainview_I static void _edi_range_color_set(Edi_Editor *editor, Edi_Range range, Edi_Color color) { - char *format; - format = strdup(color); - evas_textblock_cursor_line_set(_format_cursor, range.start.line - 1); evas_textblock_cursor_pos_set(_format_cursor, evas_textblock_cursor_pos_get(_format_cursor) + range.start.col - 1); - evas_textblock_cursor_format_prepend(_format_cursor, format); + evas_textblock_cursor_format_prepend(_format_cursor, color); - format[0] = '-'; evas_textblock_cursor_line_set(_format_cursor, range.end.line - 1); evas_textblock_cursor_pos_set(_format_cursor, evas_textblock_cursor_pos_get(_format_cursor) + range.end.col - 1); - evas_textblock_cursor_format_append(_format_cursor, format); - - free(format); + evas_textblock_cursor_format_append(_format_cursor, ""); } static void From a50fd20f06214bcb2ac84392b5068224a73e0dcc Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Tue, 21 Oct 2014 22:27:10 +0100 Subject: [PATCH 09/36] warning-- --- elm_code/lib/elm_code.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elm_code/lib/elm_code.c b/elm_code/lib/elm_code.c index 66cb04c..4dd8f95 100644 --- a/elm_code/lib/elm_code.c +++ b/elm_code/lib/elm_code.c @@ -134,7 +134,7 @@ EAPI const char *elm_code_path_get(Elm_Code_File *file) return eina_file_filename_get(file->file); } -EAPI int elm_code_lines_get(Elm_Code_File *file) +EAPI unsigned int elm_code_lines_get(Elm_Code_File *file) { return eina_list_count(file->lines); } From 383bae2def08d3a06b35e5cc1bd542f080b0b0ec Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Tue, 21 Oct 2014 22:28:12 +0100 Subject: [PATCH 10/36] Update tests to use the proper api check --- elm_code/tests/elm_code_test_load.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elm_code/tests/elm_code_test_load.c b/elm_code/tests/elm_code_test_load.c index 2431603..7dabf18 100644 --- a/elm_code/tests/elm_code_test_load.c +++ b/elm_code/tests/elm_code_test_load.c @@ -26,7 +26,7 @@ START_TEST (elm_code_load_lines) file = elm_code_open(path); - ck_assert(4 == elm_code_lines_get(file)); + ck_assert_uint_eq(4, elm_code_lines_get(file)); elm_code_close(file); } END_TEST @@ -38,7 +38,7 @@ START_TEST (elm_code_load_blank_lines) file = elm_code_open(path); - ck_assert(8 == elm_code_lines_get(file)); + ck_assert_uint_eq(8, elm_code_lines_get(file)); elm_code_close(file); } END_TEST From 3d35a3f9494a4ca440b38a9c10b81eb30da6761d Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sun, 26 Oct 2014 22:08:52 +0000 Subject: [PATCH 11/36] Add some documentation grouping --- elm_code/lib/Elm_Code.h | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/elm_code/lib/Elm_Code.h b/elm_code/lib/Elm_Code.h index e03aa26..571434c 100644 --- a/elm_code/lib/Elm_Code.h +++ b/elm_code/lib/Elm_Code.h @@ -100,6 +100,18 @@ EAPI int elm_code_init(void); */ EAPI int elm_code_shutdown(void); +/** + * @} + * + * @brief File handling functions. + * @defgroup File I/O at a file level + * + * @{ + * + * Functions for file handling within elm code. + * + */ + EAPI Elm_Code_File *elm_code_open(const char *path); EAPI void elm_code_close(Elm_Code_File *file); @@ -108,7 +120,19 @@ EAPI const char *elm_code_filename_get(Elm_Code_File *file); EAPI const char *elm_code_path_get(Elm_Code_File *file); -EAPI int elm_code_lines_get(Elm_Code_File *file); +/** + * @} + * + * @brief Content functions. + * @defgroup Content Functions for accessing file content + * + * @{ + * + * File content handling functions. + * + */ + +EAPI unsigned int elm_code_lines_get(Elm_Code_File *file); EAPI char *elm_code_line_content_get(Elm_Code_File *file, int line); From 83c0e231ecdcc499c44b716afab4a6fcc7e39256 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sun, 26 Oct 2014 22:47:27 +0000 Subject: [PATCH 12/36] Add basic structure for elm_code object - namespacing the elm_code_file properly to keep it clean --- elm_code/lib/Elm_Code.h | 54 ++++--------- elm_code/lib/Makefile.am | 5 +- elm_code/lib/elm_code.c | 88 +++------------------ elm_code/lib/elm_code_file.c | 98 ++++++++++++++++++++++++ elm_code/lib/elm_code_file.h | 71 +++++++++++++++++ elm_code/tests/Makefile.am | 3 +- elm_code/tests/elm_code_file_test_load.c | 66 ++++++++++++++++ elm_code/tests/elm_code_suite.c | 3 +- elm_code/tests/elm_code_suite.h | 3 +- elm_code/tests/elm_code_test_basic.c | 25 ++++++ elm_code/tests/elm_code_test_load.c | 66 ---------------- src/lib/Makefile.am | 5 +- 12 files changed, 298 insertions(+), 189 deletions(-) create mode 100644 elm_code/lib/elm_code_file.c create mode 100644 elm_code/lib/elm_code_file.h create mode 100644 elm_code/tests/elm_code_file_test_load.c create mode 100644 elm_code/tests/elm_code_test_basic.c delete mode 100644 elm_code/tests/elm_code_test_load.c diff --git a/elm_code/lib/Elm_Code.h b/elm_code/lib/Elm_Code.h index 571434c..d105310 100644 --- a/elm_code/lib/Elm_Code.h +++ b/elm_code/lib/Elm_Code.h @@ -5,6 +5,8 @@ #include +#include + #ifdef EAPI # undef EAPI #endif @@ -37,22 +39,15 @@ extern "C" { /** * @file - * @brief These routines are used for interacting with files using Elm Code. + * @brief These routines are used for loading Elm Code widgets. */ -typedef struct _Elm_Code_Line +typedef struct _Elm_Code { - char *content; - unsigned int number; + Elm_Code_File *file; + Eina_List *widgets; -} Elm_Code_Line; - -typedef struct _Elm_Code_File -{ - Eina_List *lines; - Eina_File *file; - -} Elm_Code_File; +} Elm_Code; /** * @brief Init / shutdown functions. @@ -101,40 +96,21 @@ EAPI int elm_code_init(void); EAPI int elm_code_shutdown(void); /** - * @} + * Create a new Elm Code instance for an existing file * - * @brief File handling functions. - * @defgroup File I/O at a file level - * - * @{ - * - * Functions for file handling within elm code. + * This method creates a new Elm Code instance backing to the specified file. + * 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_File *elm_code_open(const char *path); - -EAPI void elm_code_close(Elm_Code_File *file); - -EAPI const char *elm_code_filename_get(Elm_Code_File *file); - -EAPI const char *elm_code_path_get(Elm_Code_File *file); +EAPI Elm_Code *elm_code_create(Elm_Code_File *file); /** - * @} - * - * @brief Content functions. - * @defgroup Content Functions for accessing file content - * - * @{ - * - * File content handling functions. + * Free an Elm Code instance * + * Releases the resources retained by the code instance and any files it references. */ - -EAPI unsigned int elm_code_lines_get(Elm_Code_File *file); - -EAPI char *elm_code_line_content_get(Elm_Code_File *file, int line); +EAPI void elm_code_free(Elm_Code *code); /** * @} diff --git a/elm_code/lib/Makefile.am b/elm_code/lib/Makefile.am index 468b75a..43b95b7 100644 --- a/elm_code/lib/Makefile.am +++ b/elm_code/lib/Makefile.am @@ -10,10 +10,13 @@ AM_CPPFLAGS = \ lib_LTLIBRARIES = libelm_code.la -includes_HEADERS = Elm_Code.h +includes_HEADERS = \ +elm_code_file.h \ +Elm_Code.h includesdir = $(includedir)/edi-@VMAJ@ libelm_code_la_SOURCES = \ +elm_code_file.c \ elm_code.c libelm_code_la_LIBADD = @EFL_LIBS@ -lm libelm_code_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@ diff --git a/elm_code/lib/elm_code.c b/elm_code/lib/elm_code.c index 4dd8f95..932168e 100644 --- a/elm_code/lib/elm_code.c +++ b/elm_code/lib/elm_code.c @@ -57,92 +57,22 @@ elm_code_shutdown(void) return _elm_code_init; } -static Elm_Code_Line *_elm_code_blank_create(int line) +EAPI Elm_Code * +elm_code_create(Elm_Code_File *file) { - Elm_Code_Line *ecl; + Elm_Code *ret; - ecl = calloc(1, sizeof(Elm_Code_Line)); - if (!ecl) return NULL; - - ecl->number = line; - return ecl; -} - -EAPI Elm_Code_File *elm_code_open(const char *path) -{ - Elm_Code_File *ret; - Eina_File *file; - Eina_File_Line *line; - Eina_Iterator *it; - unsigned int lastindex; - - file = eina_file_open(path, EINA_FALSE); - ret = calloc(1, sizeof(Elm_Code_File)); + ret = calloc(1, sizeof(Elm_Code)); ret->file = file; - lastindex = 1; - - it = eina_file_map_lines(file); - EINA_ITERATOR_FOREACH(it, line) - { - Elm_Code_Line *ecl; - - /* Working around the issue that eina_file_map_lines does not trigger an item for empty lines */ - while (lastindex < line->index - 1) - { - ecl = _elm_code_blank_create(++lastindex); - if (!ecl) continue; - - ret->lines = eina_list_append(ret->lines, ecl); - } - - ecl = _elm_code_blank_create(lastindex = line->index); - if (!ecl) continue; - - ecl->content = malloc(sizeof(char) * (line->length + 1)); - strncpy(ecl->content, line->start, line->length); - ecl->content[line->length] = 0; - - ret->lines = eina_list_append(ret->lines, ecl); - } - eina_iterator_free(it); return ret; } -EAPI void elm_code_close(Elm_Code_File *file) +EAPI void +elm_code_free(Elm_Code *code) { - Elm_Code_Line *l; + if (code->file) + free(code->file); - EINA_LIST_FREE(file->lines, l) - { - if (l->content) - free(l->content); - free(l); - } - - eina_file_close(file->file); - free(file); -} - -EAPI const char *elm_code_filename_get(Elm_Code_File *file) -{ - return basename((char *)eina_file_filename_get(file->file)); -} - -EAPI const char *elm_code_path_get(Elm_Code_File *file) -{ - return eina_file_filename_get(file->file); -} - -EAPI unsigned int elm_code_lines_get(Elm_Code_File *file) -{ - return eina_list_count(file->lines); -} - -EAPI char *elm_code_line_content_get(Elm_Code_File *file, int number) -{ - Elm_Code_Line *line; - - line = eina_list_nth(file->lines, number); - return line->content; + free(code); } diff --git a/elm_code/lib/elm_code_file.c b/elm_code/lib/elm_code_file.c new file mode 100644 index 0000000..3ad76b9 --- /dev/null +++ b/elm_code/lib/elm_code_file.c @@ -0,0 +1,98 @@ +#ifdef HAVE_CONFIG +# include "config.h" +#endif + +#include "Elm_Code.h" +#include "elm_code_file.h" + +#include "elm_code_private.h" + +static Elm_Code_Line *_elm_code_blank_create(int line) +{ + Elm_Code_Line *ecl; + + ecl = calloc(1, sizeof(Elm_Code_Line)); + if (!ecl) return NULL; + + ecl->number = line; + return ecl; +} + +EAPI Elm_Code_File *elm_code_file_open(const char *path) +{ + Elm_Code_File *ret; + Eina_File *file; + Eina_File_Line *line; + Eina_Iterator *it; + unsigned int lastindex; + + file = eina_file_open(path, EINA_FALSE); + ret = calloc(1, sizeof(Elm_Code_File)); + ret->file = file; + lastindex = 1; + + it = eina_file_map_lines(file); + EINA_ITERATOR_FOREACH(it, line) + { + Elm_Code_Line *ecl; + + /* Working around the issue that eina_file_map_lines does not trigger an item for empty lines */ + while (lastindex < line->index - 1) + { + ecl = _elm_code_blank_create(++lastindex); + if (!ecl) continue; + + ret->lines = eina_list_append(ret->lines, ecl); + } + + ecl = _elm_code_blank_create(lastindex = line->index); + if (!ecl) continue; + + ecl->content = malloc(sizeof(char) * (line->length + 1)); + strncpy(ecl->content, line->start, line->length); + ecl->content[line->length] = 0; + + ret->lines = eina_list_append(ret->lines, ecl); + } + eina_iterator_free(it); + + return ret; +} + +EAPI void elm_code_file_close(Elm_Code_File *file) +{ + Elm_Code_Line *l; + + EINA_LIST_FREE(file->lines, l) + { + if (l->content) + free(l->content); + free(l); + } + + eina_file_close(file->file); + free(file); +} + +EAPI const char *elm_code_file_filename_get(Elm_Code_File *file) +{ + return basename((char *)eina_file_filename_get(file->file)); +} + +EAPI const char *elm_code_file_path_get(Elm_Code_File *file) +{ + return eina_file_filename_get(file->file); +} + +EAPI unsigned int elm_code_file_lines_get(Elm_Code_File *file) +{ + return eina_list_count(file->lines); +} + +EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, int number) +{ + Elm_Code_Line *line; + + line = eina_list_nth(file->lines, number); + return line->content; +} diff --git a/elm_code/lib/elm_code_file.h b/elm_code/lib/elm_code_file.h new file mode 100644 index 0000000..7ad7ff8 --- /dev/null +++ b/elm_code/lib/elm_code_file.h @@ -0,0 +1,71 @@ +#ifndef ELM_CODE_FILE_H_ +# define ELM_CODE_FILE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file + * @brief These routines are used for interacting with files using Elm Code. + */ + +typedef struct _Elm_Code_Line +{ + char *content; + unsigned int number; + +} Elm_Code_Line; + +typedef struct _Elm_Code_File +{ + Eina_List *lines; + Eina_File *file; + +} Elm_Code_File; + +/** + * @brief File handling functions. + * @defgroup File I/O at a file level + * + * @{ + * + * Functions for file handling within elm code. + * + */ + +EAPI Elm_Code_File *elm_code_file_open(const char *path); + +EAPI void elm_code_file_close(Elm_Code_File *file); + +EAPI const char *elm_code_file_filename_get(Elm_Code_File *file); + +EAPI const char *elm_code_file_path_get(Elm_Code_File *file); + +/** + * @} + * + * @brief Content functions. + * @defgroup Content Functions for accessing file content + * + * @{ + * + * File content handling functions. + * + */ + +EAPI unsigned int elm_code_file_lines_get(Elm_Code_File *file); + +EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, int line); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ELM_CODE_FILE_H_ */ diff --git a/elm_code/tests/Makefile.am b/elm_code/tests/Makefile.am index 5652799..a874f1c 100644 --- a/elm_code/tests/Makefile.am +++ b/elm_code/tests/Makefile.am @@ -4,7 +4,8 @@ if EFL_HAVE_TESTS check_PROGRAMS = elm_code_suite elm_code_suite_SOURCES = \ -elm_code_test_load.c \ +elm_code_file_test_load.c \ +elm_code_test_basic.c \ elm_code_suite.c elm_code_suite_CPPFLAGS = -I$(top_builddir)/elm_code/lib/ \ diff --git a/elm_code/tests/elm_code_file_test_load.c b/elm_code/tests/elm_code_file_test_load.c new file mode 100644 index 0000000..d7933ac --- /dev/null +++ b/elm_code/tests/elm_code_file_test_load.c @@ -0,0 +1,66 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "elm_code_suite.h" + +START_TEST (elm_code_file_load) +{ + char *path = "elm_code/tests/testfile.txt"; + char real[EINA_PATH_MAX]; + Elm_Code_File *file; + + file = elm_code_file_open(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); +} +END_TEST + +START_TEST (elm_code_file_load_lines) +{ + char *path = "elm_code/tests/testfile.txt"; + Elm_Code_File *file; + + file = elm_code_file_open(path); + + ck_assert_uint_eq(4, elm_code_file_lines_get(file)); + elm_code_file_close(file); +} +END_TEST + +START_TEST (elm_code_file_load_blank_lines) +{ + char *path = "elm_code/tests/testfile-withblanks.txt"; + Elm_Code_File *file; + + file = elm_code_file_open(path); + + ck_assert_uint_eq(8, elm_code_file_lines_get(file)); + elm_code_file_close(file); +} +END_TEST + +START_TEST (elm_code_file_load_content) +{ + char *path = "elm_code/tests/testfile.txt"; + Elm_Code_File *file; + + file = elm_code_file_open(path); + + ck_assert_str_eq("line2", elm_code_file_line_content_get(file, 2 - 1)); + ck_assert_str_eq("another line", elm_code_file_line_content_get(file, 4 - 1)); + elm_code_file_close(file); +} +END_TEST + +void elm_code_file_test_load(TCase *tc) +{ + tcase_add_test(tc, elm_code_file_load); + tcase_add_test(tc, elm_code_file_load_lines); + tcase_add_test(tc, elm_code_file_load_blank_lines); + tcase_add_test(tc, elm_code_file_load_content); +} + diff --git a/elm_code/tests/elm_code_suite.c b/elm_code/tests/elm_code_suite.c index 7b74ec2..9b869e8 100644 --- a/elm_code/tests/elm_code_suite.c +++ b/elm_code/tests/elm_code_suite.c @@ -13,7 +13,8 @@ static const struct { const char *name; void (*build)(TCase *tc); } tests[] = { - { "load", elm_code_test_load }, + { "file_load", elm_code_file_test_load }, + { "basic", elm_code_test_basic }, }; START_TEST(elm_code_initialization) diff --git a/elm_code/tests/elm_code_suite.h b/elm_code/tests/elm_code_suite.h index 2cdf523..2ae75a1 100644 --- a/elm_code/tests/elm_code_suite.h +++ b/elm_code/tests/elm_code_suite.h @@ -5,6 +5,7 @@ #include -void elm_code_test_load(TCase *tc); +void elm_code_file_test_load(TCase *tc); +void elm_code_test_basic(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 new file mode 100644 index 0000000..f127cfb --- /dev/null +++ b/elm_code/tests/elm_code_test_basic.c @@ -0,0 +1,25 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "elm_code_suite.h" + +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); + + ck_assert(code); + elm_code_free(code); +} +END_TEST + +void elm_code_test_basic(TCase *tc) +{ + tcase_add_test(tc, elm_code_create_test); +} + diff --git a/elm_code/tests/elm_code_test_load.c b/elm_code/tests/elm_code_test_load.c deleted file mode 100644 index 7dabf18..0000000 --- a/elm_code/tests/elm_code_test_load.c +++ /dev/null @@ -1,66 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "elm_code_suite.h" - -START_TEST (elm_code_load) -{ - char *path = "elm_code/tests/testfile.txt"; - char real[EINA_PATH_MAX]; - Elm_Code_File *file; - - file = elm_code_open(path); - realpath(path, real); - - ck_assert_str_eq(basename(path), elm_code_filename_get(file)); - ck_assert_str_eq(real, elm_code_path_get(file)); - elm_code_close(file); -} -END_TEST - -START_TEST (elm_code_load_lines) -{ - char *path = "elm_code/tests/testfile.txt"; - Elm_Code_File *file; - - file = elm_code_open(path); - - ck_assert_uint_eq(4, elm_code_lines_get(file)); - elm_code_close(file); -} -END_TEST - -START_TEST (elm_code_load_blank_lines) -{ - char *path = "elm_code/tests/testfile-withblanks.txt"; - Elm_Code_File *file; - - file = elm_code_open(path); - - ck_assert_uint_eq(8, elm_code_lines_get(file)); - elm_code_close(file); -} -END_TEST - -START_TEST (elm_code_load_content) -{ - char *path = "elm_code/tests/testfile.txt"; - Elm_Code_File *file; - - file = elm_code_open(path); - - ck_assert_str_eq("line2", elm_code_line_content_get(file, 2 - 1)); - ck_assert_str_eq("another line", elm_code_line_content_get(file, 4 - 1)); - elm_code_close(file); -} -END_TEST - -void elm_code_test_load(TCase *tc) -{ - tcase_add_test(tc, elm_code_load); - tcase_add_test(tc, elm_code_load_lines); - tcase_add_test(tc, elm_code_load_blank_lines); - tcase_add_test(tc, elm_code_load_content); -} - diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 39bb0d0..760c16d 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -10,7 +10,10 @@ AM_CPPFLAGS = \ lib_LTLIBRARIES = libedi.la -includes_HEADERS = Edi.h +includes_HEADERS = \ +edi_builder.h \ +edi_path.h \ +Edi.h includesdir = $(includedir)/edi-@VMAJ@ libedi_la_SOURCES = \ From 0ad14fac1409a54a99569722d6900b095d2ec1ee Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Tue, 4 Nov 2014 21:05:29 +0000 Subject: [PATCH 13/36] Allow appending of lines to an Elm_Code_File, allow Elm_Code_File objects to be created empty without reading from a filesystem source --- elm_code/lib/elm_code_file.c | 53 +++++++++++++++++----- elm_code/lib/elm_code_file.h | 6 +++ elm_code/tests/Makefile.am | 1 + elm_code/tests/elm_code_file_test_memory.c | 25 ++++++++++ elm_code/tests/elm_code_suite.c | 1 + elm_code/tests/elm_code_suite.h | 1 + 6 files changed, 76 insertions(+), 11 deletions(-) create mode 100644 elm_code/tests/elm_code_file_test_memory.c diff --git a/elm_code/lib/elm_code_file.c b/elm_code/lib/elm_code_file.c index 3ad76b9..0a0854c 100644 --- a/elm_code/lib/elm_code_file.c +++ b/elm_code/lib/elm_code_file.c @@ -18,6 +18,29 @@ static Elm_Code_Line *_elm_code_blank_create(int line) return ecl; } +static void _elm_code_file_line_append_data(Elm_Code_File *file, const char *content, int length, int row) +{ + Elm_Code_Line *line; + + line = _elm_code_blank_create(row); + if (!line) return; + + line->content = malloc(sizeof(char) * (length + 1)); + strncpy(line->content, content, length); + line->content[length] = 0; + + file->lines = eina_list_append(file->lines, line); +} + +EAPI Elm_Code_File *elm_code_file_new() +{ + Elm_Code_File *ret; + + ret = calloc(1, sizeof(Elm_Code_File)); + + return ret; +} + EAPI Elm_Code_File *elm_code_file_open(const char *path) { Elm_Code_File *ret; @@ -26,8 +49,8 @@ EAPI Elm_Code_File *elm_code_file_open(const char *path) Eina_Iterator *it; unsigned int lastindex; + ret = elm_code_file_new(); file = eina_file_open(path, EINA_FALSE); - ret = calloc(1, sizeof(Elm_Code_File)); ret->file = file; lastindex = 1; @@ -45,21 +68,14 @@ EAPI Elm_Code_File *elm_code_file_open(const char *path) ret->lines = eina_list_append(ret->lines, ecl); } - ecl = _elm_code_blank_create(lastindex = line->index); - if (!ecl) continue; - - ecl->content = malloc(sizeof(char) * (line->length + 1)); - strncpy(ecl->content, line->start, line->length); - ecl->content[line->length] = 0; - - ret->lines = eina_list_append(ret->lines, ecl); + _elm_code_file_line_append_data(ret, line->start, line->length, lastindex = line->index); } eina_iterator_free(it); return ret; } -EAPI void elm_code_file_close(Elm_Code_File *file) +EAPI void elm_code_file_free(Elm_Code_File *file) { Elm_Code_Line *l; @@ -70,10 +86,16 @@ EAPI void elm_code_file_close(Elm_Code_File *file) free(l); } - eina_file_close(file->file); free(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) { return basename((char *)eina_file_filename_get(file->file)); @@ -89,6 +111,15 @@ EAPI unsigned int elm_code_file_lines_get(Elm_Code_File *file) return eina_list_count(file->lines); } + +EAPI void elm_code_file_line_append(Elm_Code_File *file, const char *line) +{ + int row; + + row = elm_code_file_lines_get(file); + _elm_code_file_line_append_data(file, line, strlen(line), row+1); +} + EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, int number) { Elm_Code_Line *line; diff --git a/elm_code/lib/elm_code_file.h b/elm_code/lib/elm_code_file.h index 7ad7ff8..4f7d095 100644 --- a/elm_code/lib/elm_code_file.h +++ b/elm_code/lib/elm_code_file.h @@ -36,8 +36,12 @@ typedef struct _Elm_Code_File * */ +EAPI Elm_Code_File *elm_code_file_new(); + EAPI Elm_Code_File *elm_code_file_open(const char *path); +EAPI void elm_code_file_free(Elm_Code_File *file); + EAPI void elm_code_file_close(Elm_Code_File *file); EAPI const char *elm_code_file_filename_get(Elm_Code_File *file); @@ -58,6 +62,8 @@ EAPI const char *elm_code_file_path_get(Elm_Code_File *file); EAPI unsigned int elm_code_file_lines_get(Elm_Code_File *file); +EAPI void elm_code_file_line_append(Elm_Code_File *file, const char *line); + EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, int line); /** diff --git a/elm_code/tests/Makefile.am b/elm_code/tests/Makefile.am index a874f1c..4a5759f 100644 --- a/elm_code/tests/Makefile.am +++ b/elm_code/tests/Makefile.am @@ -5,6 +5,7 @@ check_PROGRAMS = elm_code_suite elm_code_suite_SOURCES = \ elm_code_file_test_load.c \ +elm_code_file_test_memory.c \ elm_code_test_basic.c \ elm_code_suite.c diff --git a/elm_code/tests/elm_code_file_test_memory.c b/elm_code/tests/elm_code_file_test_memory.c new file mode 100644 index 0000000..aa31649 --- /dev/null +++ b/elm_code/tests/elm_code_file_test_memory.c @@ -0,0 +1,25 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "elm_code_suite.h" + +START_TEST (elm_code_file_memory_lines) +{ + Elm_Code_File *file; + + file = elm_code_file_new(); + 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); +} +END_TEST + +void elm_code_file_test_memory(TCase *tc) +{ + tcase_add_test(tc, elm_code_file_memory_lines); +} + diff --git a/elm_code/tests/elm_code_suite.c b/elm_code/tests/elm_code_suite.c index 9b869e8..1f52521 100644 --- a/elm_code/tests/elm_code_suite.c +++ b/elm_code/tests/elm_code_suite.c @@ -14,6 +14,7 @@ static const struct { void (*build)(TCase *tc); } tests[] = { { "file_load", elm_code_file_test_load }, + { "file_memory", elm_code_file_test_memory }, { "basic", elm_code_test_basic }, }; diff --git a/elm_code/tests/elm_code_suite.h b/elm_code/tests/elm_code_suite.h index 2ae75a1..b9d1bdf 100644 --- a/elm_code/tests/elm_code_suite.h +++ b/elm_code/tests/elm_code_suite.h @@ -6,6 +6,7 @@ #include void elm_code_file_test_load(TCase *tc); +void elm_code_file_test_memory(TCase *tc); void elm_code_test_basic(TCase *tc); #endif /* _EDLM_CODE_SUITE_H */ From a28e199c7275cfbcb0b4a90ecd8d0dae331e3d1f Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Tue, 4 Nov 2014 22:21:49 +0000 Subject: [PATCH 14/36] Add an initial stab at an elm_code widget. It currently does not refresh at any time other than load or resize, so is not respecting content updates, but it's a start. Use it in place of the list of elm_label objects that were rendered in the log panel. Not colour highlighted yet, but one thing at a time. --- elm_code/lib/Elm_Code.h | 9 +-- elm_code/lib/Makefile.am | 2 + elm_code/lib/elm_code_common.h | 31 +++++++++++ elm_code/lib/elm_code_file.c | 6 +- elm_code/lib/elm_code_widget.c | 70 ++++++++++++++++++++++++ elm_code/lib/elm_code_widget.h | 39 +++++++++++++ elm_code/tests/elm_code_file_test_load.c | 4 +- src/bin/Makefile.am | 3 +- src/bin/edi_logpanel.c | 39 ++++++------- 9 files changed, 169 insertions(+), 34 deletions(-) create mode 100644 elm_code/lib/elm_code_common.h create mode 100644 elm_code/lib/elm_code_widget.c create mode 100644 elm_code/lib/elm_code_widget.h diff --git a/elm_code/lib/Elm_Code.h b/elm_code/lib/Elm_Code.h index d105310..84e4109 100644 --- a/elm_code/lib/Elm_Code.h +++ b/elm_code/lib/Elm_Code.h @@ -5,7 +5,9 @@ #include +#include #include +#include #ifdef EAPI # undef EAPI @@ -42,13 +44,6 @@ extern "C" { * @brief These routines are used for loading Elm Code widgets. */ -typedef struct _Elm_Code -{ - Elm_Code_File *file; - Eina_List *widgets; - -} Elm_Code; - /** * @brief Init / shutdown functions. * @defgroup Init Init / Shutdown diff --git a/elm_code/lib/Makefile.am b/elm_code/lib/Makefile.am index 43b95b7..98a15f6 100644 --- a/elm_code/lib/Makefile.am +++ b/elm_code/lib/Makefile.am @@ -12,11 +12,13 @@ lib_LTLIBRARIES = libelm_code.la includes_HEADERS = \ elm_code_file.h \ +elm_code_widget.h \ Elm_Code.h includesdir = $(includedir)/edi-@VMAJ@ libelm_code_la_SOURCES = \ elm_code_file.c \ +elm_code_widget.c \ elm_code.c libelm_code_la_LIBADD = @EFL_LIBS@ -lm libelm_code_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@ diff --git a/elm_code/lib/elm_code_common.h b/elm_code/lib/elm_code_common.h new file mode 100644 index 0000000..ce0993b --- /dev/null +++ b/elm_code/lib/elm_code_common.h @@ -0,0 +1,31 @@ +#ifndef ELM_CODE_COMMON_H_ +# define ELM_CODE_COMMON_H_ + +#include + +#include "elm_code_file.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file + * @brief Common data structures and constants. + */ + +typedef struct _Elm_Code +{ + Elm_Code_File *file; + Eina_List *widgets; +} Elm_Code; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ELM_CODE_COMMON_H_ */ diff --git a/elm_code/lib/elm_code_file.c b/elm_code/lib/elm_code_file.c index 0a0854c..cd6aa97 100644 --- a/elm_code/lib/elm_code_file.c +++ b/elm_code/lib/elm_code_file.c @@ -124,6 +124,10 @@ EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, int number) { Elm_Code_Line *line; - line = eina_list_nth(file->lines, number); + line = eina_list_nth(file->lines, number - 1); + printf("N %d\n", number); + + if (!line) + return NULL; return line->content; } diff --git a/elm_code/lib/elm_code_widget.c b/elm_code/lib/elm_code_widget.c new file mode 100644 index 0000000..297cd3d --- /dev/null +++ b/elm_code/lib/elm_code_widget.c @@ -0,0 +1,70 @@ +#ifdef HAVE_CONFIG +# include "config.h" +#endif + +#include + +#include "elm_code_widget.h" + +#include "elm_code_private.h" + +EAPI void elm_code_widget_fill(Evas_Object *o, Elm_Code *code) +{ + Evas_Textgrid_Cell *cells; + const char *line, *chr; + unsigned int length; + int w, h, cw, ch; + unsigned int x, y; + + evas_object_geometry_get(o, NULL, NULL, &w, &h); + evas_object_textgrid_cell_size_get(o, &cw, &ch); + evas_object_textgrid_size_set(o, ceil(((double) w) / cw), + ceil(((double) h) / ch)); + evas_object_textgrid_size_get(o, &w, &h); + + for (y = 1; y <= elm_code_file_lines_get(code->file); y++) + { + line = elm_code_file_line_content_get(code->file, y); + chr = line; + + cells = evas_object_textgrid_cellrow_get(o, y - 1); + length = strlen(line); + + for (x = 0; x < (unsigned int) w && x < length; x++) + { + cells[x].codepoint = *chr; + cells[x].bg = 0; + cells[x].fg = 1; + + chr++; + } + } +} + +static void +_elm_code_widget_resize_cb(void *data, EINA_UNUSED Evas *e, Evas_Object *obj, + EINA_UNUSED void *event_info) +{ + Elm_Code *code; + + code = (Elm_Code *)data; + elm_code_widget_fill(obj, code); +} + +EAPI Evas_Object *elm_code_widget_add(Evas_Object *parent, Elm_Code *code) +{ + Evas_Object *o; + + o = evas_object_textgrid_add(parent); + + evas_object_textgrid_font_set(o, "Mono", 10 * elm_config_scale_get()); + + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, 0, + 54, 54, 54, 255); + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, 1, + 205, 205, 205, 255); + + evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _elm_code_widget_resize_cb, code); + return o; +} + diff --git a/elm_code/lib/elm_code_widget.h b/elm_code/lib/elm_code_widget.h new file mode 100644 index 0000000..dda5df8 --- /dev/null +++ b/elm_code/lib/elm_code_widget.h @@ -0,0 +1,39 @@ +#ifndef ELM_CODE_WIDGET_H_ +# define ELM_CODE_WIDGET_H_ + +#include +#include +#include "elm_code_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file + * @brief These routines are used for rendering instances of Elm Code. + */ + +/** + * @brief UI Loading functions. + * @defgroup Init Creating a widget to render an Elm Code backend + * + * @{ + * + * Functions for UI loading. + * + */ + +EAPI Evas_Object *elm_code_widget_add(Evas_Object *parent, Elm_Code *code); +EAPI void elm_code_widget_fill(Evas_Object *o, Elm_Code *code); + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ELM_CODE_WIDGET_H_ */ diff --git a/elm_code/tests/elm_code_file_test_load.c b/elm_code/tests/elm_code_file_test_load.c index d7933ac..ff41d24 100644 --- a/elm_code/tests/elm_code_file_test_load.c +++ b/elm_code/tests/elm_code_file_test_load.c @@ -50,8 +50,8 @@ START_TEST (elm_code_file_load_content) file = elm_code_file_open(path); - ck_assert_str_eq("line2", elm_code_file_line_content_get(file, 2 - 1)); - ck_assert_str_eq("another line", elm_code_file_line_content_get(file, 4 - 1)); + 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); } END_TEST diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 1af7148..1cc9b90 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -6,6 +6,7 @@ bin_PROGRAMS = edi edi_build AM_CPPFLAGS = -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ -I$(top_builddir)/src/bin/ \ -I$(top_srcdir)/src/bin/ \ +-I$(top_srcdir)/elm_code/lib \ -I$(top_builddir)/src/lib/ \ -I$(top_srcdir)/src/lib/ \ @EFL_CFLAGS@ @@ -21,7 +22,7 @@ mainview/edi_mainview_item.c \ mainview/edi_mainview.c \ edi_main.c -edi_LDADD = @EFL_LIBS@ $(top_builddir)/src/lib/libedi.la +edi_LDADD = @EFL_LIBS@ $(top_builddir)/elm_code/lib/libelm_code.la $(top_builddir)/src/lib/libedi.la edi_build_SOURCES = \ edi_build_main.c diff --git a/src/bin/edi_logpanel.c b/src/bin/edi_logpanel.c index 20af9f6..2a79814 100644 --- a/src/bin/edi_logpanel.c +++ b/src/bin/edi_logpanel.c @@ -3,12 +3,14 @@ #endif #include +#include #include "edi_logpanel.h" #include "edi_private.h" -static Evas_Object *_info_box; +static Evas_Object *_info_widget; +static Elm_Code *_elm_code; void print_cb(const Eina_Log_Domain *domain, Eina_Log_Level level, @@ -19,7 +21,6 @@ void print_cb(const Eina_Log_Domain *domain, EINA_UNUSED void *data, va_list args) { - Evas_Object *txt; unsigned int printed, buffer_len = 512; char buffer [buffer_len]; @@ -27,39 +28,31 @@ void print_cb(const Eina_Log_Domain *domain, domain->domain_str, file, fnc, line); vsnprintf(buffer + printed, buffer_len - printed, fmt, args); - txt = elm_label_add(_info_box); + elm_code_file_line_append(_elm_code->file, buffer); +/* if (level <= EINA_LOG_LEVEL_ERR) evas_object_color_set(txt, 255, 63, 63, 255); else evas_object_color_set(txt, 255, 255, 255, 255); - - elm_object_text_set(txt, buffer); - evas_object_size_hint_weight_set(txt, EVAS_HINT_EXPAND, 0.1); - evas_object_size_hint_align_set(txt, 0.0, EVAS_HINT_FILL); - evas_object_show(txt); - - elm_box_pack_end(_info_box, txt); +*/ } void edi_logpanel_add(Evas_Object *parent) { - Evas_Object *scroll, *vbx; + Evas_Object *widget; + Elm_Code *code; - scroll = elm_scroller_add(parent); - elm_scroller_gravity_set(scroll, 0.0, 0.0); - evas_object_size_hint_weight_set(scroll, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(scroll, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_show(scroll); + code = elm_code_create(elm_code_file_new()); + 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); + evas_object_show(widget); - vbx = elm_box_add(parent); - evas_object_size_hint_weight_set(vbx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_show(vbx); - elm_object_content_set(scroll, vbx); - - _info_box = vbx; + _elm_code = code; + _info_widget = widget; eina_log_print_cb_set(print_cb, NULL); eina_log_color_disable_set(EINA_TRUE); - elm_object_content_set(parent, scroll); + elm_object_content_set(parent, widget); } From 4be9198da5e719aa8007bd3115e4531494e4c7c7 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Wed, 5 Nov 2014 00:01:28 +0000 Subject: [PATCH 15/36] Adding some initial concept of status flags for a line and default enum to start working on color pallette in our widget. Load enough colors to provide these statuses and hook into the EDI log panel implementation --- elm_code/lib/elm_code_common.h | 15 +++++++++++++++ elm_code/lib/elm_code_file.c | 11 ++++++++--- elm_code/lib/elm_code_file.h | 8 +++++++- elm_code/lib/elm_code_widget.c | 23 +++++++++++++++-------- src/bin/edi_logpanel.c | 14 ++++++++------ 5 files changed, 53 insertions(+), 18 deletions(-) diff --git a/elm_code/lib/elm_code_common.h b/elm_code/lib/elm_code_common.h index ce0993b..5e288bf 100644 --- a/elm_code/lib/elm_code_common.h +++ b/elm_code/lib/elm_code_common.h @@ -3,6 +3,21 @@ #include +typedef enum { + ELM_CODE_STATUS_TYPE_DEFAULT = 0, + ELM_CODE_STATUS_TYPE_ERROR, + + ELM_CODE_STATUS_TYPE_COUNT +} Elm_Code_Status_Type; + + +typedef enum { + ELM_CODE_TOKEN_TYPE_DEFAULT = ELM_CODE_STATUS_TYPE_COUNT, + + ELM_CODE_TOKEN_TYPE_COUNT +} Elm_Code_Token_Type; + + #include "elm_code_file.h" #ifdef __cplusplus diff --git a/elm_code/lib/elm_code_file.c b/elm_code/lib/elm_code_file.c index cd6aa97..b05a8d0 100644 --- a/elm_code/lib/elm_code_file.c +++ b/elm_code/lib/elm_code_file.c @@ -15,6 +15,7 @@ static Elm_Code_Line *_elm_code_blank_create(int line) if (!ecl) return NULL; ecl->number = line; + ecl->status = ELM_CODE_STATUS_TYPE_DEFAULT; return ecl; } @@ -120,12 +121,16 @@ EAPI void elm_code_file_line_append(Elm_Code_File *file, const char *line) _elm_code_file_line_append_data(file, line, strlen(line), row+1); } -EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, int number) +EAPI Elm_Code_Line *elm_code_file_line_get(Elm_Code_File *file, unsigned int number) +{ + return eina_list_nth(file->lines, number - 1); +} + +EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, unsigned int number) { Elm_Code_Line *line; - line = eina_list_nth(file->lines, number - 1); - printf("N %d\n", number); + line = elm_code_file_line_get(file, number); if (!line) return NULL; diff --git a/elm_code/lib/elm_code_file.h b/elm_code/lib/elm_code_file.h index 4f7d095..726684b 100644 --- a/elm_code/lib/elm_code_file.h +++ b/elm_code/lib/elm_code_file.h @@ -3,6 +3,8 @@ #include +#include "elm_code_common.h" + #ifdef __cplusplus extern "C" { #endif @@ -17,6 +19,8 @@ typedef struct _Elm_Code_Line char *content; unsigned int number; + Elm_Code_Status_Type status; + } Elm_Code_Line; typedef struct _Elm_Code_File @@ -64,7 +68,9 @@ EAPI unsigned int elm_code_file_lines_get(Elm_Code_File *file); EAPI void elm_code_file_line_append(Elm_Code_File *file, const char *line); -EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, int line); +EAPI Elm_Code_Line *elm_code_file_line_get(Elm_Code_File *file, unsigned int line); + +EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, unsigned int line); /** * @} diff --git a/elm_code/lib/elm_code_widget.c b/elm_code/lib/elm_code_widget.c index 297cd3d..a0cb66e 100644 --- a/elm_code/lib/elm_code_widget.c +++ b/elm_code/lib/elm_code_widget.c @@ -10,8 +10,9 @@ EAPI void elm_code_widget_fill(Evas_Object *o, Elm_Code *code) { + Elm_Code_Line *line; Evas_Textgrid_Cell *cells; - const char *line, *chr; + const char *content, *chr; unsigned int length; int w, h, cw, ch; unsigned int x, y; @@ -24,17 +25,18 @@ EAPI void elm_code_widget_fill(Evas_Object *o, Elm_Code *code) for (y = 1; y <= elm_code_file_lines_get(code->file); y++) { - line = elm_code_file_line_content_get(code->file, y); - chr = line; + line = elm_code_file_line_get(code->file, y); + content = elm_code_file_line_content_get(code->file, y); + chr = content; cells = evas_object_textgrid_cellrow_get(o, y - 1); - length = strlen(line); + length = strlen(content); for (x = 0; x < (unsigned int) w && x < length; x++) { cells[x].codepoint = *chr; - cells[x].bg = 0; - cells[x].fg = 1; + cells[x].bg = line->status; + cells[x].fg = ELM_CODE_TOKEN_TYPE_DEFAULT; chr++; } @@ -59,9 +61,14 @@ EAPI Evas_Object *elm_code_widget_add(Evas_Object *parent, Elm_Code *code) evas_object_textgrid_font_set(o, "Mono", 10 * elm_config_scale_get()); - evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, 0, + // setup status colors + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_DEFAULT, 54, 54, 54, 255); - evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, 1, + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_ERROR, + 205, 54, 54, 255); + + // setup token colors + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_TOKEN_TYPE_DEFAULT, 205, 205, 205, 255); evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _elm_code_widget_resize_cb, code); diff --git a/src/bin/edi_logpanel.c b/src/bin/edi_logpanel.c index 2a79814..17b8ae8 100644 --- a/src/bin/edi_logpanel.c +++ b/src/bin/edi_logpanel.c @@ -21,7 +21,8 @@ void print_cb(const Eina_Log_Domain *domain, EINA_UNUSED void *data, va_list args) { - unsigned int printed, buffer_len = 512; + Elm_Code_Line *code_line; + unsigned int printed, line_count, buffer_len = 512; char buffer [buffer_len]; printed = snprintf(buffer, buffer_len, "%s:%s:%s (%d): ", @@ -29,12 +30,13 @@ void print_cb(const Eina_Log_Domain *domain, vsnprintf(buffer + printed, buffer_len - printed, fmt, args); elm_code_file_line_append(_elm_code->file, buffer); -/* if (level <= EINA_LOG_LEVEL_ERR) - evas_object_color_set(txt, 255, 63, 63, 255); - else - evas_object_color_set(txt, 255, 255, 255, 255); -*/ + { + line_count = elm_code_file_lines_get(_elm_code->file); + code_line = elm_code_file_line_get(_elm_code->file, line_count); + + code_line->status = ELM_CODE_STATUS_TYPE_ERROR; + } } void edi_logpanel_add(Evas_Object *parent) From 4eec76793b777e827e5c1ca560f89a33c770f5e3 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Wed, 5 Nov 2014 13:36:54 +0000 Subject: [PATCH 16/36] Fix a crash when resizing if the file is longer than the viewport --- elm_code/lib/elm_code_widget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elm_code/lib/elm_code_widget.c b/elm_code/lib/elm_code_widget.c index a0cb66e..b048b47 100644 --- a/elm_code/lib/elm_code_widget.c +++ b/elm_code/lib/elm_code_widget.c @@ -23,7 +23,7 @@ EAPI void elm_code_widget_fill(Evas_Object *o, Elm_Code *code) ceil(((double) h) / ch)); evas_object_textgrid_size_get(o, &w, &h); - for (y = 1; y <= elm_code_file_lines_get(code->file); y++) + for (y = 1; y <= (unsigned int) h && y <= elm_code_file_lines_get(code->file); y++) { line = elm_code_file_line_get(code->file, y); content = elm_code_file_line_content_get(code->file, y); From 051e03ba99ee151c88ef1d381009edefd98861e0 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Wed, 5 Nov 2014 13:55:37 +0000 Subject: [PATCH 17/36] Add a simple elm_code_test binary that loads the widget and inserts some demo text --- .gitignore | 2 + configure.ac | 1 + elm_code/Makefile.am | 2 +- elm_code/bin/Makefile.am | 19 ++ elm_code/bin/elm_code_test_main.c | 127 ++++++++++++ elm_code/bin/elm_code_test_private.h | 6 + elm_code/bin/gettext.h | 280 +++++++++++++++++++++++++++ 7 files changed, 436 insertions(+), 1 deletion(-) create mode 100644 elm_code/bin/Makefile.am create mode 100644 elm_code/bin/elm_code_test_main.c create mode 100644 elm_code/bin/elm_code_test_private.h create mode 100644 elm_code/bin/gettext.h diff --git a/.gitignore b/.gitignore index 51a23b6..25477c4 100644 --- a/.gitignore +++ b/.gitignore @@ -64,6 +64,8 @@ po/stamp-po /src/tests/test-suite.log /src/tests/check-results.xml +/elm_code/bin/elm_code_test + /elm_code/tests/elm_code_suite /elm_code/tests/elm_code_suite.* /elm_code/tests/test-suite.log diff --git a/configure.ac b/configure.ac index 5ef2c99..78d544f 100644 --- a/configure.ac +++ b/configure.ac @@ -103,6 +103,7 @@ src/lib/Makefile src/tests/Makefile elm_code/Makefile elm_code/lib/Makefile +elm_code/bin/Makefile elm_code/tests/Makefile doc/edi.1 ]) diff --git a/elm_code/Makefile.am b/elm_code/Makefile.am index d01d7e3..15871c9 100644 --- a/elm_code/Makefile.am +++ b/elm_code/Makefile.am @@ -1,4 +1,4 @@ MAINTAINERCLEANFILES = Makefile.in -SUBDIRS = lib tests +SUBDIRS = lib bin tests diff --git a/elm_code/bin/Makefile.am b/elm_code/bin/Makefile.am new file mode 100644 index 0000000..d2a4d25 --- /dev/null +++ b/elm_code/bin/Makefile.am @@ -0,0 +1,19 @@ +MAINTAINERCLEANFILES = Makefile.in + +bin_PROGRAMS = elm_code_test + +AM_CPPFLAGS = -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ +-I$(top_builddir)/elm_code/bin/ \ +-I$(top_srcdir)/elm_code/bin/ \ +-I$(top_builddir)/elm_code/lib/ \ +-I$(top_srcdir)/elm_code/lib/ \ +@EFL_CFLAGS@ + +elm_code_test_SOURCES = elm_code_test_main.c +elm_code_test_LDADD = @EFL_LIBS@ $(top_builddir)/elm_code/lib/libelm_code.la + +localedir = $(datadir)/locale +DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@ + +EXTRA_DIST = elm_code_test_private.h + diff --git a/elm_code/bin/elm_code_test_main.c b/elm_code/bin/elm_code_test_main.c new file mode 100644 index 0000000..42c0d10 --- /dev/null +++ b/elm_code/bin/elm_code_test_main.c @@ -0,0 +1,127 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +/* NOTE: Respecting header order is important for portability. + * Always put system first, then EFL, then your public header, + * and finally your private one. */ + +#include +#include + +#include "gettext.h" + +#include + +#include "elm_code_test_private.h" + +#define COPYRIGHT "Copyright © 2014 andy and various contributors (see AUTHORS)." + +static void +_elm_code_test_win_del(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + elm_exit(); +} + +static Evas_Object * +elm_code_test_win_setup(void) +{ + Evas_Object *win; + Elm_Code *code; + Elm_Code_Line *line; + Evas_Object *widget; + + win = elm_win_util_standard_add("main", "Elm_code_test"); + if (!win) return NULL; + + elm_win_focus_highlight_enabled_set(win, EINA_TRUE); + evas_object_smart_callback_add(win, "delete,request", _elm_code_test_win_del, NULL); + + code = elm_code_create(elm_code_file_new()); + widget = elm_code_widget_add(win, code); + elm_code_file_line_append(code->file, "Hello World, Elm Code!"); + elm_code_file_line_append(code->file, ""); + elm_code_file_line_append(code->file, "This is a demo of elm_code's capabilities."); + + elm_code_file_line_append(code->file, "*** Currently experimental ***"); + line = elm_code_file_line_get(code->file, 4); + line->status = ELM_CODE_STATUS_TYPE_ERROR; + + 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); + evas_object_show(widget); + + elm_win_resize_object_add(win, widget); + + evas_object_resize(win, 280 * elm_config_scale_get(), 70 * elm_config_scale_get()); + evas_object_show(win); + + return win; +} + +static const Ecore_Getopt optdesc = { + "elm_code_test", + "%prog [options]", + PACKAGE_VERSION, + COPYRIGHT, + "BSD with advertisement clause", + "An EFL elm_code_test program", + 0, + { + ECORE_GETOPT_LICENSE('L', "license"), + ECORE_GETOPT_COPYRIGHT('C', "copyright"), + ECORE_GETOPT_VERSION('V', "version"), + ECORE_GETOPT_HELP('h', "help"), + ECORE_GETOPT_SENTINEL + } +}; + +EAPI_MAIN int +elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED) +{ + Evas_Object *win; + int args; + Eina_Bool quit_option = EINA_FALSE; + + Ecore_Getopt_Value values[] = { + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_NONE + }; + +#if ENABLE_NLS + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + bind_textdomain_codeset(PACKAGE, "UTF-8"); + textdomain(PACKAGE); +#endif + + elm_code_init(); + + args = ecore_getopt_parse(&optdesc, values, argc, argv); + if (args < 0) + { + EINA_LOG_CRIT("Could not parse arguments."); + goto end; + } + else if (quit_option) + { + goto end; + } + + elm_app_info_set(elm_main, "elm_code_test", "images/elm_code.png"); + + if (!(win = elm_code_test_win_setup())) + goto end; + + elm_run(); + + end: + elm_code_shutdown(); + elm_shutdown(); + + return 0; +} +ELM_MAIN() diff --git a/elm_code/bin/elm_code_test_private.h b/elm_code/bin/elm_code_test_private.h new file mode 100644 index 0000000..04fb817 --- /dev/null +++ b/elm_code/bin/elm_code_test_private.h @@ -0,0 +1,6 @@ +#ifndef ELM_CODE_TEST_PRIVATE_H_ +# define ELM_CODE_TEST_PRIVATE_H_ + +// FIXME: put some private stuff related to your binary + +#endif diff --git a/elm_code/bin/gettext.h b/elm_code/bin/gettext.h new file mode 100644 index 0000000..e76b592 --- /dev/null +++ b/elm_code/bin/gettext.h @@ -0,0 +1,280 @@ +/* Convenience header for conditional use of GNU . + Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. */ + +#ifndef _LIBGETTEXT_H +#define _LIBGETTEXT_H 1 + +/* NLS can be disabled through the configure --disable-nls option. */ +#if ENABLE_NLS + +/* Get declarations of GNU message catalog functions. */ +# include + +/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by + the gettext() and ngettext() macros. This is an alternative to calling + textdomain(), and is useful for libraries. */ +# ifdef DEFAULT_TEXT_DOMAIN +# undef gettext +# define gettext(Msgid) \ + dgettext (DEFAULT_TEXT_DOMAIN, Msgid) +# undef ngettext +# define ngettext(Msgid1, Msgid2, N) \ + dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) +# endif + +#else + +/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which + chokes if dcgettext is defined as a macro. So include it now, to make + later inclusions of a NOP. We don't include + as well because people using "gettext.h" will not include , + and also including would fail on SunOS 4, whereas + is OK. */ +#if defined(__sun) +# include +#endif + +/* Many header files from the libstdc++ coming with g++ 3.3 or newer include + , which chokes if dcgettext is defined as a macro. So include + it now, to make later inclusions of a NOP. */ +#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) +# include +# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H +# include +# endif +#endif + +/* Disabled NLS. + The casts to 'const char *' serve the purpose of producing warnings + for invalid uses of the value returned from these functions. + On pre-ANSI systems without 'const', the config.h file is supposed to + contain "#define const". */ +# undef gettext +# define gettext(Msgid) ((const char *) (Msgid)) +# undef dgettext +# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) +# undef dcgettext +# define dcgettext(Domainname, Msgid, Category) \ + ((void) (Category), dgettext (Domainname, Msgid)) +# undef ngettext +# define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 \ + ? ((void) (Msgid2), (const char *) (Msgid1)) \ + : ((void) (Msgid1), (const char *) (Msgid2))) +# undef dngettext +# define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) +# undef dcngettext +# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N)) +# undef textdomain +# define textdomain(Domainname) ((const char *) (Domainname)) +# undef bindtextdomain +# define bindtextdomain(Domainname, Dirname) \ + ((void) (Domainname), (const char *) (Dirname)) +# undef bind_textdomain_codeset +# define bind_textdomain_codeset(Domainname, Codeset) \ + ((void) (Domainname), (const char *) (Codeset)) + +#endif + +/* A pseudo function call that serves as a marker for the automated + extraction of messages, but does not call gettext(). The run-time + translation is done at a different place in the code. + The argument, String, should be a literal string. Concatenated strings + and other string expressions won't work. + The macro's expansion is not parenthesized, so that it is suitable as + initializer for static 'char[]' or 'const char[]' variables. */ +#define gettext_noop(String) String + +/* The separator between msgctxt and msgid in a .mo file. */ +#define GETTEXT_CONTEXT_GLUE "\004" + +/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a + MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be + short and rarely need to change. + The letter 'p' stands for 'particular' or 'special'. */ +#ifdef DEFAULT_TEXT_DOMAIN +# define pgettext(Msgctxt, Msgid) \ + pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) +#else +# define pgettext(Msgctxt, Msgid) \ + pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) +#endif +#define dpgettext(Domainname, Msgctxt, Msgid) \ + pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) +#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \ + pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category) +#ifdef DEFAULT_TEXT_DOMAIN +# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ + npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) +#else +# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ + npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) +#endif +#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ + npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) +#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \ + npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category) + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static const char * +pgettext_aux (const char *domain, + const char *msg_ctxt_id, const char *msgid, + int category) +{ + const char *translation = dcgettext (domain, msg_ctxt_id, category); + if (translation == msg_ctxt_id) + return msgid; + else + return translation; +} + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static const char * +npgettext_aux (const char *domain, + const char *msg_ctxt_id, const char *msgid, + const char *msgid_plural, unsigned long int n, + int category) +{ + const char *translation = + dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); + if (translation == msg_ctxt_id || translation == msgid_plural) + return (n == 1 ? msgid : msgid_plural); + else + return translation; +} + +/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID + can be arbitrary expressions. But for string literals these macros are + less efficient than those above. */ + +#include + +#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \ + (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \ + /* || __STDC_VERSION__ >= 199901L */ ) + +#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS +#include +#endif + +#define pgettext_expr(Msgctxt, Msgid) \ + dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES) +#define dpgettext_expr(Domainname, Msgctxt, Msgid) \ + dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES) + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static const char * +dcpgettext_expr (const char *domain, + const char *msgctxt, const char *msgid, + int category) +{ + size_t msgctxt_len = strlen (msgctxt) + 1; + size_t msgid_len = strlen (msgid) + 1; + const char *translation; +#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS + char msg_ctxt_id[msgctxt_len + msgid_len]; +#else + char buf[1024]; + char *msg_ctxt_id = + (msgctxt_len + msgid_len <= sizeof (buf) + ? buf + : (char *) malloc (msgctxt_len + msgid_len)); + if (msg_ctxt_id != NULL) +#endif + { + memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); + msg_ctxt_id[msgctxt_len - 1] = '\004'; + memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); + translation = dcgettext (domain, msg_ctxt_id, category); +#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS + if (msg_ctxt_id != buf) + free (msg_ctxt_id); +#endif + if (translation != msg_ctxt_id) + return translation; + } + return msgid; +} + +#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \ + dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) +#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ + dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static const char * +dcnpgettext_expr (const char *domain, + const char *msgctxt, const char *msgid, + const char *msgid_plural, unsigned long int n, + int category) +{ + size_t msgctxt_len = strlen (msgctxt) + 1; + size_t msgid_len = strlen (msgid) + 1; + const char *translation; +#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS + char msg_ctxt_id[msgctxt_len + msgid_len]; +#else + char buf[1024]; + char *msg_ctxt_id = + (msgctxt_len + msgid_len <= sizeof (buf) + ? buf + : (char *) malloc (msgctxt_len + msgid_len)); + if (msg_ctxt_id != NULL) +#endif + { + memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); + msg_ctxt_id[msgctxt_len - 1] = '\004'; + memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); + translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); +#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS + if (msg_ctxt_id != buf) + free (msg_ctxt_id); +#endif + if (!(translation == msg_ctxt_id || translation == msgid_plural)) + return translation; + } + return (n == 1 ? msgid : msgid_plural); +} + +#endif /* _LIBGETTEXT_H */ From fdccc03a4a564223d1c1d4c9ae6cb3ecfddcbc01 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Thu, 6 Nov 2014 23:43:56 +0000 Subject: [PATCH 18/36] Passing Eo events from Elm_Code to the Evas_Object when the backend data changes. Track a list of all widgets connected to the Elm_Code so we can signal them all. Add API to change status of a line which will refresh the widget too. --- configure.ac | 1 + elm_code/lib/Elm_Code.h | 15 ++++++++++ elm_code/lib/elm_code.c | 28 ++++++++++++++++++- elm_code/lib/elm_code_common.h | 10 ++++++- elm_code/lib/elm_code_file.c | 18 ++++++++++++ elm_code/lib/elm_code_file.h | 4 +++ elm_code/lib/elm_code_widget.c | 50 ++++++++++++++++++++++++++++++++-- src/bin/edi_logpanel.c | 4 +-- 8 files changed, 122 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index 78d544f..a4080f3 100644 --- a/configure.ac +++ b/configure.ac @@ -34,6 +34,7 @@ PKG_CHECK_MODULES([EFL], evas >= 1.8.0 ecore >= 1.8.0 edje >= 1.8.0 + eo >= 1.8.0 elementary >= 1.8.0 eio >= 1.8.0 ]) diff --git a/elm_code/lib/Elm_Code.h b/elm_code/lib/Elm_Code.h index 84e4109..8e0528d 100644 --- a/elm_code/lib/Elm_Code.h +++ b/elm_code/lib/Elm_Code.h @@ -107,6 +107,21 @@ EAPI Elm_Code *elm_code_create(Elm_Code_File *file); */ EAPI void elm_code_free(Elm_Code *code); +/** + * @} + * + * @brief Callbacks and message passing. + * @defgroup Callbacks Managing the information flow between Elm_Code objects and Evas_Object widgets + * + * @{ + * + * Managing the callbacks and other behaviours that cross the backend - frontend divide. + */ + + +EAPI void elm_code_callback_fire(Elm_Code *code, const char *signal, void *data); + + /** * @} */ diff --git a/elm_code/lib/elm_code.c b/elm_code/lib/elm_code.c index 932168e..7f43b7e 100644 --- a/elm_code/lib/elm_code.c +++ b/elm_code/lib/elm_code.c @@ -2,6 +2,9 @@ # include "config.h" #endif +#define EFL_BETA_API_SUPPORT +#include + #include "Elm_Code.h" #include "elm_code_private.h" @@ -64,6 +67,7 @@ elm_code_create(Elm_Code_File *file) ret = calloc(1, sizeof(Elm_Code)); ret->file = file; + file->parent = ret; return ret; } @@ -71,8 +75,30 @@ elm_code_create(Elm_Code_File *file) EAPI void elm_code_free(Elm_Code *code) { + Eina_List *item; + Evas_Object *widget; + if (code->file) - free(code->file); + elm_code_file_free(code->file); + + EINA_LIST_FOREACH(code->widgets, item, widget) + { + evas_object_hide(widget); + evas_object_del(widget); + } free(code); } + +EAPI void +elm_code_callback_fire(Elm_Code *code, const char *signal, void *data) +{ + Eina_List *item; + Evas_Object *widget; + + EINA_LIST_FOREACH(code->widgets, item, widget) + { + eo_do(widget, eo_event_callback_call(ELM_CODE_EVENT_LINE_SET_DONE, data)); + } +} + diff --git a/elm_code/lib/elm_code_common.h b/elm_code/lib/elm_code_common.h index 5e288bf..aac0969 100644 --- a/elm_code/lib/elm_code_common.h +++ b/elm_code/lib/elm_code_common.h @@ -3,6 +3,13 @@ #include +#define EFL_BETA_API_SUPPORT +#include + +#define ELM_CODE_EVENT_LINE_SET_DONE "line,set,done" +//EAPI const Eo_Event_Description ELM_CODE_EVENT_LINE_SET_DONE = +// EO_EVENT_DESCRIPTION("line,set,done", ""); + typedef enum { ELM_CODE_STATUS_TYPE_DEFAULT = 0, ELM_CODE_STATUS_TYPE_ERROR, @@ -17,13 +24,14 @@ typedef enum { ELM_CODE_TOKEN_TYPE_COUNT } Elm_Code_Token_Type; - #include "elm_code_file.h" #ifdef __cplusplus extern "C" { #endif + + /** * @file * @brief Common data structures and constants. diff --git a/elm_code/lib/elm_code_file.c b/elm_code/lib/elm_code_file.c index b05a8d0..585465e 100644 --- a/elm_code/lib/elm_code_file.c +++ b/elm_code/lib/elm_code_file.c @@ -31,6 +31,9 @@ static void _elm_code_file_line_append_data(Elm_Code_File *file, const char *con line->content[length] = 0; file->lines = eina_list_append(file->lines, line); + + if (file->parent) + elm_code_callback_fire(file->parent, ELM_CODE_EVENT_LINE_SET_DONE, line); } EAPI Elm_Code_File *elm_code_file_new() @@ -136,3 +139,18 @@ EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, unsigned int numb return NULL; return line->content; } + +EAPI void elm_code_file_line_status_set(Elm_Code_File *file, unsigned int number, Elm_Code_Status_Type status) +{ + Elm_Code_Line *line; + + line = elm_code_file_line_get(file, number); + + if (!line) + return; + + line->status = status; + + if (file->parent) + elm_code_callback_fire(file->parent, ELM_CODE_EVENT_LINE_SET_DONE, line); +} diff --git a/elm_code/lib/elm_code_file.h b/elm_code/lib/elm_code_file.h index 726684b..3ea1e4b 100644 --- a/elm_code/lib/elm_code_file.h +++ b/elm_code/lib/elm_code_file.h @@ -25,6 +25,8 @@ typedef struct _Elm_Code_Line typedef struct _Elm_Code_File { + void *parent; + Eina_List *lines; Eina_File *file; @@ -72,6 +74,8 @@ EAPI Elm_Code_Line *elm_code_file_line_get(Elm_Code_File *file, unsigned int lin EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, unsigned int line); +EAPI void elm_code_file_line_status_set(Elm_Code_File *file, unsigned int line, Elm_Code_Status_Type status); + /** * @} */ diff --git a/elm_code/lib/elm_code_widget.c b/elm_code/lib/elm_code_widget.c index b048b47..52be408 100644 --- a/elm_code/lib/elm_code_widget.c +++ b/elm_code/lib/elm_code_widget.c @@ -2,6 +2,9 @@ # include "config.h" #endif +#define EFL_BETA_API_SUPPORT +#include + #include #include "elm_code_widget.h" @@ -12,7 +15,8 @@ EAPI void elm_code_widget_fill(Evas_Object *o, Elm_Code *code) { Elm_Code_Line *line; Evas_Textgrid_Cell *cells; - const char *content, *chr; + const char *content; + char *chr; unsigned int length; int w, h, cw, ch; unsigned int x, y; @@ -41,11 +45,47 @@ EAPI void elm_code_widget_fill(Evas_Object *o, Elm_Code *code) chr++; } } + + evas_object_textgrid_update_add(o, 0, 0, w, h); } static void -_elm_code_widget_resize_cb(void *data, EINA_UNUSED Evas *e, Evas_Object *obj, - EINA_UNUSED void *event_info) +_elm_code_widget_line_cb(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, + void *event_info) +{ + Elm_Code *code; + Elm_Code_Line *line; + Evas_Object *o; + + Evas_Textgrid_Cell *cells; + char *chr; + unsigned int length, x; + int w; + + code = (Elm_Code *)data; + line = (Elm_Code_Line *)event_info; + o = (Evas_Object *)obj; + + cells = evas_object_textgrid_cellrow_get(o, line->number - 1); + length = strlen(line->content); + evas_object_textgrid_size_get(o, &w, NULL); + + chr = line->content; + for (x = 0; x < (unsigned int) w && x < length; x++) + { + cells[x].codepoint = *chr; + cells[x].bg = line->status; + cells[x].fg = ELM_CODE_TOKEN_TYPE_DEFAULT; + + chr++; + } + + evas_object_textgrid_update_add(o, 0, line->number - 1, w, 1); +} + +static void +_elm_code_widget_resize_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, + void *event_info EINA_UNUSED) { Elm_Code *code; @@ -72,6 +112,10 @@ EAPI Evas_Object *elm_code_widget_add(Evas_Object *parent, Elm_Code *code) 205, 205, 205, 255); evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _elm_code_widget_resize_cb, code); + + eo_do(o,eo_event_callback_add(ELM_CODE_EVENT_LINE_SET_DONE, _elm_code_widget_line_cb, code)); + + code->widgets = eina_list_append(code->widgets, o); return o; } diff --git a/src/bin/edi_logpanel.c b/src/bin/edi_logpanel.c index 17b8ae8..ec4ae74 100644 --- a/src/bin/edi_logpanel.c +++ b/src/bin/edi_logpanel.c @@ -21,7 +21,6 @@ void print_cb(const Eina_Log_Domain *domain, EINA_UNUSED void *data, va_list args) { - Elm_Code_Line *code_line; unsigned int printed, line_count, buffer_len = 512; char buffer [buffer_len]; @@ -33,9 +32,8 @@ void print_cb(const Eina_Log_Domain *domain, if (level <= EINA_LOG_LEVEL_ERR) { line_count = elm_code_file_lines_get(_elm_code->file); - code_line = elm_code_file_line_get(_elm_code->file, line_count); - code_line->status = ELM_CODE_STATUS_TYPE_ERROR; + elm_code_file_line_status_set(_elm_code->file, line_count, ELM_CODE_STATUS_TYPE_ERROR); } } From 742e70186cc9d248c59ab414569b7040f0ad86cf Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sun, 9 Nov 2014 00:47:00 +0000 Subject: [PATCH 19/36] Take line coloring to the end of the line --- elm_code/lib/elm_code_widget.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/elm_code/lib/elm_code_widget.c b/elm_code/lib/elm_code_widget.c index 52be408..16ea4e2 100644 --- a/elm_code/lib/elm_code_widget.c +++ b/elm_code/lib/elm_code_widget.c @@ -44,6 +44,12 @@ EAPI void elm_code_widget_fill(Evas_Object *o, Elm_Code *code) chr++; } + for (; x < (unsigned int) w; x++) + { + cells[x].codepoint = 0; + cells[x].bg = line->status; + cells[x].fg = ELM_CODE_TOKEN_TYPE_DEFAULT; + } } evas_object_textgrid_update_add(o, 0, 0, w, h); @@ -79,6 +85,12 @@ _elm_code_widget_line_cb(void *data, Eo *obj, const Eo_Event_Description *desc E chr++; } + for (; x < (unsigned int) w; x++) + { + cells[x].codepoint = 0; + cells[x].bg = line->status; + cells[x].fg = ELM_CODE_TOKEN_TYPE_DEFAULT; + } evas_object_textgrid_update_add(o, 0, line->number - 1, w, 1); } From f8a92218da984b6500e7fe22fb0c1aca00d0460b Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sun, 9 Nov 2014 14:44:35 +0000 Subject: [PATCH 20/36] Add some simple version control status for lines too. Add a simple display of how that could work to elm_code_tesst --- elm_code/bin/elm_code_test_main.c | 98 ++++++++++++++++++++++++++----- elm_code/lib/elm_code_common.h | 4 ++ elm_code/lib/elm_code_widget.c | 11 +++- 3 files changed, 97 insertions(+), 16 deletions(-) diff --git a/elm_code/bin/elm_code_test_main.c b/elm_code/bin/elm_code_test_main.c index 42c0d10..c88f985 100644 --- a/elm_code/bin/elm_code_test_main.c +++ b/elm_code/bin/elm_code_test_main.c @@ -24,36 +24,106 @@ _elm_code_test_win_del(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, voi } static Evas_Object * -elm_code_test_win_setup(void) +_elm_code_test_welcome_setup(Evas_Object *parent) { - Evas_Object *win; Elm_Code *code; - Elm_Code_Line *line; Evas_Object *widget; - win = elm_win_util_standard_add("main", "Elm_code_test"); - if (!win) return NULL; - - elm_win_focus_highlight_enabled_set(win, EINA_TRUE); - evas_object_smart_callback_add(win, "delete,request", _elm_code_test_win_del, NULL); - code = elm_code_create(elm_code_file_new()); - widget = elm_code_widget_add(win, code); + widget = elm_code_widget_add(parent, code); elm_code_file_line_append(code->file, "Hello World, Elm Code!"); elm_code_file_line_append(code->file, ""); elm_code_file_line_append(code->file, "This is a demo of elm_code's capabilities."); elm_code_file_line_append(code->file, "*** Currently experimental ***"); - line = elm_code_file_line_get(code->file, 4); - line->status = ELM_CODE_STATUS_TYPE_ERROR; + elm_code_file_line_status_set(code->file, 4, ELM_CODE_STATUS_TYPE_ERROR); 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); evas_object_show(widget); - elm_win_resize_object_add(win, widget); + return widget; +} - evas_object_resize(win, 280 * elm_config_scale_get(), 70 * elm_config_scale_get()); +static Evas_Object * +_elm_code_test_diff_setup(Evas_Object *parent) +{ + Elm_Code *code; + Evas_Object *widget, *hbox; + + hbox = elm_box_add(parent); + evas_object_size_hint_weight_set(hbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(hbox, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_box_homogeneous_set(hbox, EINA_TRUE); + elm_box_horizontal_set(hbox, EINA_TRUE); + evas_object_show(hbox); + + // left side of diff + code = elm_code_create(elm_code_file_new()); + widget = elm_code_widget_add(parent, code); + + elm_code_file_line_append(code->file, "Some content to diff"); + elm_code_file_line_append(code->file, ""); + elm_code_file_line_append(code->file, "more"); + elm_code_file_line_append(code->file, "removed"); + elm_code_file_line_append(code->file, "will change"); + elm_code_file_line_append(code->file, "unchanged"); + + elm_code_file_line_status_set(code->file, 4, ELM_CODE_STATUS_TYPE_REMOVED); + elm_code_file_line_status_set(code->file, 5, ELM_CODE_STATUS_TYPE_CHANGED); + + 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); + evas_object_show(widget); + elm_box_pack_end(hbox, widget); + + // right side of diff + code = elm_code_create(elm_code_file_new()); + widget = elm_code_widget_add(parent, code); + + elm_code_file_line_append(code->file, "Some content to diff"); + elm_code_file_line_append(code->file, "added"); + elm_code_file_line_append(code->file, "more"); + elm_code_file_line_append(code->file, ""); + elm_code_file_line_append(code->file, "changed"); + elm_code_file_line_append(code->file, "unchanged"); + + elm_code_file_line_status_set(code->file, 2, ELM_CODE_STATUS_TYPE_ADDED); + elm_code_file_line_status_set(code->file, 5, ELM_CODE_STATUS_TYPE_CHANGED); + + 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); + evas_object_show(widget); + elm_box_pack_end(hbox, widget); + + return hbox; +} + +static Evas_Object * +elm_code_test_win_setup(void) +{ + Evas_Object *win; + Evas_Object *vbox; + + win = elm_win_util_standard_add("main", "Elm_code_test"); + if (!win) return NULL; + + vbox = elm_box_add(win); + evas_object_size_hint_weight_set(vbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(vbox, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_box_homogeneous_set(vbox, EINA_TRUE); + evas_object_show(vbox); + + elm_win_focus_highlight_enabled_set(win, EINA_TRUE); + evas_object_smart_callback_add(win, "delete,request", _elm_code_test_win_del, NULL); + + elm_box_pack_end(vbox, _elm_code_test_welcome_setup(vbox)); + + elm_box_pack_end(vbox, _elm_code_test_diff_setup(vbox)); + + elm_win_resize_object_add(win, vbox); + + evas_object_resize(win, 320 * elm_config_scale_get(), 180 * elm_config_scale_get()); evas_object_show(win); return win; diff --git a/elm_code/lib/elm_code_common.h b/elm_code/lib/elm_code_common.h index aac0969..76cfa2c 100644 --- a/elm_code/lib/elm_code_common.h +++ b/elm_code/lib/elm_code_common.h @@ -14,6 +14,10 @@ typedef enum { ELM_CODE_STATUS_TYPE_DEFAULT = 0, ELM_CODE_STATUS_TYPE_ERROR, + ELM_CODE_STATUS_TYPE_ADDED, + ELM_CODE_STATUS_TYPE_REMOVED, + ELM_CODE_STATUS_TYPE_CHANGED, + ELM_CODE_STATUS_TYPE_COUNT } Elm_Code_Status_Type; diff --git a/elm_code/lib/elm_code_widget.c b/elm_code/lib/elm_code_widget.c index 16ea4e2..5133172 100644 --- a/elm_code/lib/elm_code_widget.c +++ b/elm_code/lib/elm_code_widget.c @@ -115,9 +115,16 @@ EAPI Evas_Object *elm_code_widget_add(Evas_Object *parent, Elm_Code *code) // setup status colors evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_DEFAULT, - 54, 54, 54, 255); + 54, 54, 54, 255); evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_ERROR, - 205, 54, 54, 255); + 205, 54, 54, 255); + + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_ADDED, + 54, 125, 54, 255); + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_REMOVED, + 125, 54, 54, 255); + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_CHANGED, + 54, 54, 125, 255); // setup token colors evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_TOKEN_TYPE_DEFAULT, From e3fd501e9bfe0776e4917f502f1f31ee957a3861 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sun, 9 Nov 2014 18:07:03 +0000 Subject: [PATCH 21/36] Fixing some warnings. Not ideal handling of the Eo_Event_Description but it's less warn-tastic --- elm_code/lib/elm_code.c | 2 +- elm_code/lib/elm_code_common.h | 4 +--- elm_code/lib/elm_code_widget.c | 15 +++++++-------- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/elm_code/lib/elm_code.c b/elm_code/lib/elm_code.c index 7f43b7e..0186f83 100644 --- a/elm_code/lib/elm_code.c +++ b/elm_code/lib/elm_code.c @@ -98,7 +98,7 @@ elm_code_callback_fire(Elm_Code *code, const char *signal, void *data) EINA_LIST_FOREACH(code->widgets, item, widget) { - eo_do(widget, eo_event_callback_call(ELM_CODE_EVENT_LINE_SET_DONE, data)); + eo_do(widget, eo_event_callback_call((Eo_Event_Description *)signal, data)); } } diff --git a/elm_code/lib/elm_code_common.h b/elm_code/lib/elm_code_common.h index 76cfa2c..436bd45 100644 --- a/elm_code/lib/elm_code_common.h +++ b/elm_code/lib/elm_code_common.h @@ -3,9 +3,7 @@ #include -#define EFL_BETA_API_SUPPORT -#include - +// TODO figure out how this can be fixed #define ELM_CODE_EVENT_LINE_SET_DONE "line,set,done" //EAPI const Eo_Event_Description ELM_CODE_EVENT_LINE_SET_DONE = // EO_EVENT_DESCRIPTION("line,set,done", ""); diff --git a/elm_code/lib/elm_code_widget.c b/elm_code/lib/elm_code_widget.c index 5133172..02a4f87 100644 --- a/elm_code/lib/elm_code_widget.c +++ b/elm_code/lib/elm_code_widget.c @@ -31,7 +31,7 @@ EAPI void elm_code_widget_fill(Evas_Object *o, Elm_Code *code) { line = elm_code_file_line_get(code->file, y); content = elm_code_file_line_content_get(code->file, y); - chr = content; + chr = (char *)content; cells = evas_object_textgrid_cellrow_get(o, y - 1); length = strlen(content); @@ -55,11 +55,10 @@ EAPI void elm_code_widget_fill(Evas_Object *o, Elm_Code *code) evas_object_textgrid_update_add(o, 0, 0, w, h); } -static void -_elm_code_widget_line_cb(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, - void *event_info) +static Eina_Bool +_elm_code_widget_line_cb(void *data EINA_UNUSED, Eo *obj, + const Eo_Event_Description *desc EINA_UNUSED, void *event_info) { - Elm_Code *code; Elm_Code_Line *line; Evas_Object *o; @@ -68,7 +67,6 @@ _elm_code_widget_line_cb(void *data, Eo *obj, const Eo_Event_Description *desc E unsigned int length, x; int w; - code = (Elm_Code *)data; line = (Elm_Code_Line *)event_info; o = (Evas_Object *)obj; @@ -76,7 +74,7 @@ _elm_code_widget_line_cb(void *data, Eo *obj, const Eo_Event_Description *desc E length = strlen(line->content); evas_object_textgrid_size_get(o, &w, NULL); - chr = line->content; + chr = (char *)line->content; for (x = 0; x < (unsigned int) w && x < length; x++) { cells[x].codepoint = *chr; @@ -93,6 +91,7 @@ _elm_code_widget_line_cb(void *data, Eo *obj, const Eo_Event_Description *desc E } evas_object_textgrid_update_add(o, 0, line->number - 1, w, 1); + return EINA_TRUE; } static void @@ -132,7 +131,7 @@ EAPI Evas_Object *elm_code_widget_add(Evas_Object *parent, Elm_Code *code) evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _elm_code_widget_resize_cb, code); - eo_do(o,eo_event_callback_add(ELM_CODE_EVENT_LINE_SET_DONE, _elm_code_widget_line_cb, code)); + eo_do(o,eo_event_callback_add((Eo_Event_Description *)ELM_CODE_EVENT_LINE_SET_DONE, _elm_code_widget_line_cb, code)); code->widgets = eina_list_append(code->widgets, o); return o; From 131a686c782ae95e6f57a8915cddfe270adae989 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sun, 9 Nov 2014 21:53:30 +0000 Subject: [PATCH 22/36] Fix the types of Eo Events - addresses lots of compiler warnings --- elm_code/bin/Makefile.am | 1 + elm_code/lib/Elm_Code.h | 4 ++-- elm_code/lib/Makefile.am | 1 + elm_code/lib/elm_code.c | 8 +++++--- elm_code/lib/elm_code_common.h | 6 ++---- elm_code/lib/elm_code_file.c | 4 ++-- elm_code/lib/elm_code_widget.c | 4 +--- src/bin/Makefile.am | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/elm_code/bin/Makefile.am b/elm_code/bin/Makefile.am index d2a4d25..363beb8 100644 --- a/elm_code/bin/Makefile.am +++ b/elm_code/bin/Makefile.am @@ -7,6 +7,7 @@ AM_CPPFLAGS = -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ -I$(top_srcdir)/elm_code/bin/ \ -I$(top_builddir)/elm_code/lib/ \ -I$(top_srcdir)/elm_code/lib/ \ +-DEFL_BETA_API_SUPPORT \ @EFL_CFLAGS@ elm_code_test_SOURCES = elm_code_test_main.c diff --git a/elm_code/lib/Elm_Code.h b/elm_code/lib/Elm_Code.h index 8e0528d..fbc0a4b 100644 --- a/elm_code/lib/Elm_Code.h +++ b/elm_code/lib/Elm_Code.h @@ -2,7 +2,7 @@ # define ELM_CODE_H_ #include - +#include #include #include @@ -119,7 +119,7 @@ EAPI void elm_code_free(Elm_Code *code); */ -EAPI void elm_code_callback_fire(Elm_Code *code, const char *signal, void *data); +EAPI void elm_code_callback_fire(Elm_Code *code, const Eo_Event_Description *signal, void *data); /** diff --git a/elm_code/lib/Makefile.am b/elm_code/lib/Makefile.am index 98a15f6..8329e65 100644 --- a/elm_code/lib/Makefile.am +++ b/elm_code/lib/Makefile.am @@ -5,6 +5,7 @@ AM_CPPFLAGS = \ -I$(top_builddir)/elm_code/lib \ -DPACKAGE_LIB_DIR=\"$(libdir)\" \ -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ +-DEFL_BETA_API_SUPPORT \ @EFL_CFLAGS@ \ -DEFL_EFL_BUILD diff --git a/elm_code/lib/elm_code.c b/elm_code/lib/elm_code.c index 0186f83..9ae1ade 100644 --- a/elm_code/lib/elm_code.c +++ b/elm_code/lib/elm_code.c @@ -2,7 +2,6 @@ # include "config.h" #endif -#define EFL_BETA_API_SUPPORT #include #include "Elm_Code.h" @@ -12,6 +11,9 @@ static int _elm_code_init = 0; int _elm_code_lib_log_dom = -1; +const Eo_Event_Description ELM_CODE_EVENT_LINE_SET_DONE = + EO_EVENT_DESCRIPTION("line,set,done", ""); + EAPI int elm_code_init(void) { @@ -91,14 +93,14 @@ elm_code_free(Elm_Code *code) } EAPI void -elm_code_callback_fire(Elm_Code *code, const char *signal, void *data) +elm_code_callback_fire(Elm_Code *code, const Eo_Event_Description *signal, void *data) { Eina_List *item; Evas_Object *widget; EINA_LIST_FOREACH(code->widgets, item, widget) { - eo_do(widget, eo_event_callback_call((Eo_Event_Description *)signal, data)); + eo_do(widget, eo_event_callback_call(signal, data)); } } diff --git a/elm_code/lib/elm_code_common.h b/elm_code/lib/elm_code_common.h index 436bd45..11149fe 100644 --- a/elm_code/lib/elm_code_common.h +++ b/elm_code/lib/elm_code_common.h @@ -1,12 +1,10 @@ #ifndef ELM_CODE_COMMON_H_ # define ELM_CODE_COMMON_H_ +#include #include -// TODO figure out how this can be fixed -#define ELM_CODE_EVENT_LINE_SET_DONE "line,set,done" -//EAPI const Eo_Event_Description ELM_CODE_EVENT_LINE_SET_DONE = -// EO_EVENT_DESCRIPTION("line,set,done", ""); +EAPI extern const Eo_Event_Description ELM_CODE_EVENT_LINE_SET_DONE; typedef enum { ELM_CODE_STATUS_TYPE_DEFAULT = 0, diff --git a/elm_code/lib/elm_code_file.c b/elm_code/lib/elm_code_file.c index 585465e..1f5f8a8 100644 --- a/elm_code/lib/elm_code_file.c +++ b/elm_code/lib/elm_code_file.c @@ -33,7 +33,7 @@ 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_callback_fire(file->parent, &ELM_CODE_EVENT_LINE_SET_DONE, line); } EAPI Elm_Code_File *elm_code_file_new() @@ -152,5 +152,5 @@ EAPI void elm_code_file_line_status_set(Elm_Code_File *file, unsigned int number line->status = status; if (file->parent) - elm_code_callback_fire(file->parent, ELM_CODE_EVENT_LINE_SET_DONE, line); + elm_code_callback_fire(file->parent, &ELM_CODE_EVENT_LINE_SET_DONE, line); } diff --git a/elm_code/lib/elm_code_widget.c b/elm_code/lib/elm_code_widget.c index 02a4f87..ba25461 100644 --- a/elm_code/lib/elm_code_widget.c +++ b/elm_code/lib/elm_code_widget.c @@ -2,9 +2,7 @@ # include "config.h" #endif -#define EFL_BETA_API_SUPPORT #include - #include #include "elm_code_widget.h" @@ -131,7 +129,7 @@ EAPI Evas_Object *elm_code_widget_add(Evas_Object *parent, Elm_Code *code) evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _elm_code_widget_resize_cb, code); - eo_do(o,eo_event_callback_add((Eo_Event_Description *)ELM_CODE_EVENT_LINE_SET_DONE, _elm_code_widget_line_cb, code)); + eo_do(o,eo_event_callback_add(&ELM_CODE_EVENT_LINE_SET_DONE, _elm_code_widget_line_cb, code)); code->widgets = eina_list_append(code->widgets, o); return o; diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 1cc9b90..35bc17f 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -8,7 +8,7 @@ AM_CPPFLAGS = -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ -I$(top_srcdir)/src/bin/ \ -I$(top_srcdir)/elm_code/lib \ -I$(top_builddir)/src/lib/ \ --I$(top_srcdir)/src/lib/ \ +-DEFL_BETA_API_SUPPORT \ @EFL_CFLAGS@ edi_SOURCES = \ From 34b928c72c20b353863156f27e4793fc30f4838c Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sun, 9 Nov 2014 14:08:52 +0000 Subject: [PATCH 23/36] Adding simple build check and clean support to the CLI and main toolbar --- src/bin/edi_build_main.c | 21 ++++++++++++++++--- src/bin/edi_main.c | 44 +++++++++++++++++++++++++++++++++------- src/lib/edi_builder.c | 17 ++++++++++++++++ src/lib/edi_builder.h | 20 ++++++++++++++++++ 4 files changed, 92 insertions(+), 10 deletions(-) diff --git a/src/bin/edi_build_main.c b/src/bin/edi_build_main.c index 50a887a..893275c 100644 --- a/src/bin/edi_build_main.c +++ b/src/bin/edi_build_main.c @@ -40,7 +40,7 @@ _exe_del(void *d EINA_UNUSED, int t EINA_UNUSED, void *event_info EINA_UNUSED) static const Ecore_Getopt optdesc = { "edi_build", - "%prog [options]", + "%prog [options] [build-type]", PACKAGE_VERSION, COPYRIGHT, "BSD with advertisement clause", @@ -59,7 +59,7 @@ EAPI_MAIN int main(int argc EINA_UNUSED, char **argv EINA_UNUSED) { int args; - char path[PATH_MAX]; + char path[PATH_MAX], *build_type = NULL; Eina_Bool quit_option = EINA_FALSE; Ecore_Getopt_Value values[] = { @@ -102,11 +102,26 @@ main(int argc EINA_UNUSED, char **argv EINA_UNUSED) goto exit; } + if (args < argc) + build_type = argv[args]; + if (!build_type) + build_type = "build"; + ecore_event_handler_add(ECORE_EXE_EVENT_DATA, _exe_data, NULL); ecore_event_handler_add(ECORE_EXE_EVENT_ERROR, _exe_data, NULL); ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _exe_del, NULL); - edi_builder_build(); + if (!strncmp("clean", build_type, 5)) + edi_builder_clean(); + else if (!strncmp("test", build_type, 4)) + edi_builder_test(); + else if (!strncmp("build", build_type, 5)) + edi_builder_build(); + else + { + fprintf(stderr, "Unrecognised build type - try build, test or clean.\n"); + goto end; + } ecore_main_loop_begin(); end: diff --git a/src/bin/edi_main.c b/src/bin/edi_main.c index 1912797..6385c3d 100644 --- a/src/bin/edi_main.c +++ b/src/bin/edi_main.c @@ -303,10 +303,10 @@ _tb_goto_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUS evas_object_show(popup); } -static void -_tb_build_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) +static Eina_Bool +_edi_build_prep(Evas_Object *button) { - elm_toolbar_item_selected_set(elm_toolbar_selected_item_get(obj), EINA_FALSE); + elm_toolbar_item_selected_set(elm_toolbar_selected_item_get(button), EINA_FALSE); edi_consolepanel_clear(); edi_consolepanel_show(); @@ -314,11 +314,38 @@ _tb_build_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNU if (!edi_builder_can_build()) { edi_consolepanel_append_error_line("Cowardly refusing to build unknown project type."); + return EINA_FALSE; } - else - { - edi_builder_build(); - } + + return EINA_TRUE; +} + +static void +_tb_build_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + if (_edi_build_prep(obj)) + edi_builder_build(); +} + +static void +_tb_test_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + if (_edi_build_prep(obj)) + edi_builder_test(); +} +/* +static void +_tb_run_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + if (_edi_build_prep(obj)) + edi_builder_run(); +} +*/ +static void +_tb_clean_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + if (_edi_build_prep(obj)) + edi_builder_clean(); } static Evas_Object * @@ -357,6 +384,9 @@ edi_toolbar_setup(Evas_Object *win) elm_toolbar_item_separator_set(tb_it, EINA_TRUE); tb_it = elm_toolbar_item_append(tb, "system-run", "Build", _tb_build_cb, NULL); + tb_it = elm_toolbar_item_append(tb, "emblem-default", "Test", _tb_test_cb, NULL); +// tb_it = elm_toolbar_item_append(tb, "player-play", "Run", _tb_run_cb, NULL); + tb_it = elm_toolbar_item_append(tb, "edit-clear", "Clean", _tb_clean_cb, NULL); evas_object_show(tb); return tb; diff --git a/src/lib/edi_builder.c b/src/lib/edi_builder.c index 31a82bf..017e63f 100644 --- a/src/lib/edi_builder.c +++ b/src/lib/edi_builder.c @@ -50,3 +50,20 @@ edi_builder_build(void) _edi_builder_build_autogen(); } +EAPI void +edi_builder_test(void) +{ + chdir(edi_project_get()); + ecore_exe_pipe_run("make check", ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | + ECORE_EXE_PIPE_ERROR_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR, NULL); +} + +EAPI void +edi_builder_clean(void) +{ + chdir(edi_project_get()); + ecore_exe_pipe_run("make clean", ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | + ECORE_EXE_PIPE_ERROR_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR, NULL); +} + + diff --git a/src/lib/edi_builder.h b/src/lib/edi_builder.h index dcb8462..c8b0730 100644 --- a/src/lib/edi_builder.h +++ b/src/lib/edi_builder.h @@ -44,6 +44,26 @@ edi_builder_can_build(void); EAPI void edi_builder_build(void); +/** + * Run a test build for the current project. + * + * @see edi_builder_can_build(). + * + * @ingroup Builder + */ +EAPI void +edi_builder_test(void); + +/** + * Run a clean for the current project. + * + * @see edi_builder_can_build(). + * + * @ingroup Builder + */ +EAPI void +edi_builder_clean(void); + /** * @} */ From f429afa47d67e7edb3c78783dc952ceb50af5250 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Wed, 12 Nov 2014 14:05:56 +0000 Subject: [PATCH 24/36] Fix compilation of tests --- elm_code/tests/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/elm_code/tests/Makefile.am b/elm_code/tests/Makefile.am index 4a5759f..aa71521 100644 --- a/elm_code/tests/Makefile.am +++ b/elm_code/tests/Makefile.am @@ -12,6 +12,7 @@ elm_code_suite.c elm_code_suite_CPPFLAGS = -I$(top_builddir)/elm_code/lib/ \ -DPACKAGE_TESTS_DIR=\"$(top_srcdir)/elm_code/tests/\" \ -DPACKAGE_BUILD_DIR=\"`pwd`/$(top_builddir)/elm_code/tests/\" \ +-DEFL_BETA_API_SUPPORT \ @EFL_CFLAGS@ \ @CHECK_CFLAGS@ From c28dd39224f9fd6e5679f682232d0ccb7367f861 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Wed, 12 Nov 2014 22:59:05 +0000 Subject: [PATCH 25/36] Add a file load callback also - respect that with a widget refresh when called --- elm_code/lib/elm_code.c | 2 ++ elm_code/lib/elm_code_common.h | 1 + elm_code/lib/elm_code_file.c | 2 ++ elm_code/lib/elm_code_widget.c | 16 ++++++++++++++++ 4 files changed, 21 insertions(+) diff --git a/elm_code/lib/elm_code.c b/elm_code/lib/elm_code.c index 9ae1ade..fb40c9f 100644 --- a/elm_code/lib/elm_code.c +++ b/elm_code/lib/elm_code.c @@ -13,6 +13,8 @@ int _elm_code_lib_log_dom = -1; const Eo_Event_Description ELM_CODE_EVENT_LINE_SET_DONE = EO_EVENT_DESCRIPTION("line,set,done", ""); +const Eo_Event_Description ELM_CODE_EVENT_FILE_LOAD_DONE = + EO_EVENT_DESCRIPTION("file, load,done", ""); EAPI int elm_code_init(void) diff --git a/elm_code/lib/elm_code_common.h b/elm_code/lib/elm_code_common.h index 11149fe..bae3599 100644 --- a/elm_code/lib/elm_code_common.h +++ b/elm_code/lib/elm_code_common.h @@ -5,6 +5,7 @@ #include EAPI extern const Eo_Event_Description ELM_CODE_EVENT_LINE_SET_DONE; +EAPI extern const Eo_Event_Description ELM_CODE_EVENT_FILE_LOAD_DONE; typedef enum { ELM_CODE_STATUS_TYPE_DEFAULT = 0, diff --git a/elm_code/lib/elm_code_file.c b/elm_code/lib/elm_code_file.c index 1f5f8a8..9650b33 100644 --- a/elm_code/lib/elm_code_file.c +++ b/elm_code/lib/elm_code_file.c @@ -76,6 +76,8 @@ 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); return ret; } diff --git a/elm_code/lib/elm_code_widget.c b/elm_code/lib/elm_code_widget.c index ba25461..760334f 100644 --- a/elm_code/lib/elm_code_widget.c +++ b/elm_code/lib/elm_code_widget.c @@ -92,6 +92,21 @@ _elm_code_widget_line_cb(void *data EINA_UNUSED, Eo *obj, return EINA_TRUE; } + +static Eina_Bool +_elm_code_widget_file_cb(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Evas_Object *o; + Elm_Code *code; + + code = (Elm_Code *)data; + o = (Evas_Object *)obj; + + elm_code_widget_fill(o, code); + return EINA_TRUE; +} + static void _elm_code_widget_resize_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) @@ -130,6 +145,7 @@ EAPI Evas_Object *elm_code_widget_add(Evas_Object *parent, Elm_Code *code) evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _elm_code_widget_resize_cb, code); eo_do(o,eo_event_callback_add(&ELM_CODE_EVENT_LINE_SET_DONE, _elm_code_widget_line_cb, code)); + eo_do(o,eo_event_callback_add(&ELM_CODE_EVENT_FILE_LOAD_DONE, _elm_code_widget_file_cb, code)); code->widgets = eina_list_append(code->widgets, o); return o; From b88b087a84d8fa621704dad5a62e65e957f7777e Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Wed, 12 Nov 2014 23:43:18 +0000 Subject: [PATCH 26/36] Fix issue where console error items would not open when tapped --- src/bin/edi_main.c | 7 +++++-- src/lib/edi.c | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/bin/edi_main.c b/src/bin/edi_main.c index 6385c3d..b475512 100644 --- a/src/bin/edi_main.c +++ b/src/bin/edi_main.c @@ -411,16 +411,18 @@ _edi_exit(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info } EAPI Evas_Object * -edi_open(const char *path) +edi_open(const char *inputpath) { Evas_Object *win, *vbx, *content, *tb; const char *winname; + char *path; - if (!edi_project_set(path)) + if (!edi_project_set(inputpath)) { fprintf(stderr, "Project path must be a directory\n"); return NULL; } + path = realpath(inputpath, NULL); elm_need_ethumb(); elm_need_efreet(); @@ -451,6 +453,7 @@ edi_open(const char *path) evas_object_resize(win, 560 * elm_config_scale_get(), 420 * elm_config_scale_get()); evas_object_show(win); + free(path); return win; } diff --git a/src/lib/edi.c b/src/lib/edi.c index 8950a49..3c4aec4 100644 --- a/src/lib/edi.c +++ b/src/lib/edi.c @@ -79,7 +79,7 @@ edi_project_set(const char *path) { char *real = NULL; - real = realpath(real, NULL); + real = realpath(path, NULL); if (!_edi_path_isdir(path)) { free(real); @@ -89,7 +89,7 @@ edi_project_set(const char *path) if (_edi_project_path) eina_stringshare_del(_edi_project_path); - _edi_project_path = eina_stringshare_add(path); + _edi_project_path = eina_stringshare_add(real); free(real); return EINA_TRUE; } From 99e6dfbbd9bf806aad53ad9c43e916530411e25e Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Thu, 13 Nov 2014 21:34:47 +0000 Subject: [PATCH 27/36] Add a simple token system to allow us to render some text styles --- elm_code/bin/elm_code_test_main.c | 1 + elm_code/lib/elm_code_common.h | 1 + elm_code/lib/elm_code_file.c | 20 ++++ elm_code/lib/elm_code_file.h | 13 +++ elm_code/lib/elm_code_widget.c | 125 +++++++++++++-------- elm_code/tests/elm_code_file_test_memory.c | 17 +++ 6 files changed, 128 insertions(+), 49 deletions(-) diff --git a/elm_code/bin/elm_code_test_main.c b/elm_code/bin/elm_code_test_main.c index c88f985..40f73bf 100644 --- a/elm_code/bin/elm_code_test_main.c +++ b/elm_code/bin/elm_code_test_main.c @@ -32,6 +32,7 @@ _elm_code_test_welcome_setup(Evas_Object *parent) code = elm_code_create(elm_code_file_new()); 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); elm_code_file_line_append(code->file, ""); elm_code_file_line_append(code->file, "This is a demo of elm_code's capabilities."); diff --git a/elm_code/lib/elm_code_common.h b/elm_code/lib/elm_code_common.h index bae3599..e19a6b3 100644 --- a/elm_code/lib/elm_code_common.h +++ b/elm_code/lib/elm_code_common.h @@ -21,6 +21,7 @@ typedef enum { typedef enum { ELM_CODE_TOKEN_TYPE_DEFAULT = ELM_CODE_STATUS_TYPE_COUNT, + ELM_CODE_TOKEN_TYPE_COMMENT, ELM_CODE_TOKEN_TYPE_COUNT } Elm_Code_Token_Type; diff --git a/elm_code/lib/elm_code_file.c b/elm_code/lib/elm_code_file.c index 9650b33..e649b28 100644 --- a/elm_code/lib/elm_code_file.c +++ b/elm_code/lib/elm_code_file.c @@ -156,3 +156,23 @@ EAPI void elm_code_file_line_status_set(Elm_Code_File *file, unsigned int number if (file->parent) elm_code_callback_fire(file->parent, &ELM_CODE_EVENT_LINE_SET_DONE, line); } + +EAPI void elm_code_file_line_token_add(Elm_Code_File *file, unsigned int number, int start, int end, + Elm_Code_Token_Type type) +{ + Elm_Code_Line *line; + Elm_Code_Token *tok; + + line = elm_code_file_line_get(file, number); + tok = calloc(1, sizeof(Elm_Code_Token)); + + tok->start = start; + tok->end = end; + tok->type = type; + + line->tokens = eina_list_append(line->tokens, tok); + + if (file->parent) + elm_code_callback_fire(file->parent, &ELM_CODE_EVENT_LINE_SET_DONE, line); +} + diff --git a/elm_code/lib/elm_code_file.h b/elm_code/lib/elm_code_file.h index 3ea1e4b..0950ed9 100644 --- a/elm_code/lib/elm_code_file.h +++ b/elm_code/lib/elm_code_file.h @@ -14,12 +14,22 @@ extern "C" { * @brief These routines are used for interacting with files using Elm Code. */ +typedef struct _Elm_Code_Token +{ + int start, end; + + Elm_Code_Token_Type type; + +} Elm_Code_Token; + typedef struct _Elm_Code_Line { char *content; unsigned int number; Elm_Code_Status_Type status; + Eina_List *tokens; + } Elm_Code_Line; @@ -76,6 +86,9 @@ EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, unsigned int line EAPI void elm_code_file_line_status_set(Elm_Code_File *file, unsigned int line, Elm_Code_Status_Type status); +EAPI void elm_code_file_line_token_add(Elm_Code_File *file, unsigned int number, int start, int end, + Elm_Code_Token_Type type); + /** * @} */ diff --git a/elm_code/lib/elm_code_widget.c b/elm_code/lib/elm_code_widget.c index 760334f..011afdb 100644 --- a/elm_code/lib/elm_code_widget.c +++ b/elm_code/lib/elm_code_widget.c @@ -9,48 +9,93 @@ #include "elm_code_private.h" -EAPI void elm_code_widget_fill(Evas_Object *o, Elm_Code *code) +static Eina_Bool _elm_code_widget_resize(Evas_Object *o) { - Elm_Code_Line *line; - Evas_Textgrid_Cell *cells; - const char *content; - char *chr; - unsigned int length; int w, h, cw, ch; - unsigned int x, y; evas_object_geometry_get(o, NULL, NULL, &w, &h); evas_object_textgrid_cell_size_get(o, &cw, &ch); evas_object_textgrid_size_set(o, ceil(((double) w) / cw), ceil(((double) h) / ch)); + + return h > 0 && w > 0; +} + +static void _elm_code_widget_fill_line_token(Evas_Textgrid_Cell *cells, int count, int start, int end, Elm_Code_Token_Type type) +{ + int x; + + for (x = start - 1; x < end && x < count; x++) + { + cells[x].fg = type; + } +} + +static void _elm_code_widget_fill_line(Evas_Object *o, Evas_Textgrid_Cell *cells, Elm_Code_Line *line) +{ + Eina_List *item; + Elm_Code_Token *token; + + char *chr; + unsigned int length, x; + int w, start; + + if (!_elm_code_widget_resize(o)) + return; + + length = strlen(line->content); + evas_object_textgrid_size_get(o, &w, NULL); + + chr = (char *)line->content; + for (x = 0; x < (unsigned int) w && x < length; x++) + { + cells[x].codepoint = *chr; + cells[x].bg = line->status; + + chr++; + } + for (; x < (unsigned int) w; x++) + { + cells[x].codepoint = 0; + cells[x].bg = line->status; + } + + start = 1; + + EINA_LIST_FOREACH(line->tokens, item, token) + { + + _elm_code_widget_fill_line_token(cells, w, start, token->start, ELM_CODE_TOKEN_TYPE_DEFAULT); + + // TODO handle a token starting before the previous finishes + _elm_code_widget_fill_line_token(cells, w, token->start, token->end, token->type); + + start = token->end + 1; + } + + _elm_code_widget_fill_line_token(cells, w, start, length, ELM_CODE_TOKEN_TYPE_DEFAULT); + + evas_object_textgrid_update_add(o, 0, line->number - 1, w, 1); +} + +EAPI void elm_code_widget_fill(Evas_Object *o, Elm_Code *code) +{ + Elm_Code_Line *line; + Evas_Textgrid_Cell *cells; + int w, h; + unsigned int y; + + if (!_elm_code_widget_resize(o)) + return; evas_object_textgrid_size_get(o, &w, &h); for (y = 1; y <= (unsigned int) h && y <= elm_code_file_lines_get(code->file); y++) { line = elm_code_file_line_get(code->file, y); - content = elm_code_file_line_content_get(code->file, y); - chr = (char *)content; cells = evas_object_textgrid_cellrow_get(o, y - 1); - length = strlen(content); - - for (x = 0; x < (unsigned int) w && x < length; x++) - { - cells[x].codepoint = *chr; - cells[x].bg = line->status; - cells[x].fg = ELM_CODE_TOKEN_TYPE_DEFAULT; - - chr++; - } - for (; x < (unsigned int) w; x++) - { - cells[x].codepoint = 0; - cells[x].bg = line->status; - cells[x].fg = ELM_CODE_TOKEN_TYPE_DEFAULT; - } + _elm_code_widget_fill_line(o, cells, line); } - - evas_object_textgrid_update_add(o, 0, 0, w, h); } static Eina_Bool @@ -61,34 +106,13 @@ _elm_code_widget_line_cb(void *data EINA_UNUSED, Eo *obj, Evas_Object *o; Evas_Textgrid_Cell *cells; - char *chr; - unsigned int length, x; - int w; line = (Elm_Code_Line *)event_info; o = (Evas_Object *)obj; cells = evas_object_textgrid_cellrow_get(o, line->number - 1); - length = strlen(line->content); - evas_object_textgrid_size_get(o, &w, NULL); + _elm_code_widget_fill_line(o, cells, line); - chr = (char *)line->content; - for (x = 0; x < (unsigned int) w && x < length; x++) - { - cells[x].codepoint = *chr; - cells[x].bg = line->status; - cells[x].fg = ELM_CODE_TOKEN_TYPE_DEFAULT; - - chr++; - } - for (; x < (unsigned int) w; x++) - { - cells[x].codepoint = 0; - cells[x].bg = line->status; - cells[x].fg = ELM_CODE_TOKEN_TYPE_DEFAULT; - } - - evas_object_textgrid_update_add(o, 0, line->number - 1, w, 1); return EINA_TRUE; } @@ -114,6 +138,7 @@ _elm_code_widget_resize_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, Elm_Code *code; code = (Elm_Code *)data; + elm_code_widget_fill(obj, code); } @@ -141,6 +166,8 @@ EAPI Evas_Object *elm_code_widget_add(Evas_Object *parent, Elm_Code *code) // setup token colors evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_TOKEN_TYPE_DEFAULT, 205, 205, 205, 255); + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_TOKEN_TYPE_COMMENT, + 54, 205, 255, 255); evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _elm_code_widget_resize_cb, code); diff --git a/elm_code/tests/elm_code_file_test_memory.c b/elm_code/tests/elm_code_file_test_memory.c index aa31649..21d2ce5 100644 --- a/elm_code/tests/elm_code_file_test_memory.c +++ b/elm_code/tests/elm_code_file_test_memory.c @@ -18,8 +18,25 @@ START_TEST (elm_code_file_memory_lines) } END_TEST +START_TEST (elm_code_file_memory_tokens) +{ + Elm_Code_File *file; + Elm_Code_Line *line; + + file = elm_code_file_new(); + + 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); +} +END_TEST + void elm_code_file_test_memory(TCase *tc) { tcase_add_test(tc, elm_code_file_memory_lines); + tcase_add_test(tc, elm_code_file_memory_tokens); } From 3350a896ed50db4d9e3824e595795fba8a5a0a86 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Thu, 13 Nov 2014 21:35:58 +0000 Subject: [PATCH 28/36] change the colour of strings - does not seem to apply to all strangely, will dig further into CLANG tokens later --- src/bin/editor/edi_editor.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/bin/editor/edi_editor.c b/src/bin/editor/edi_editor.c index 4ab6155..2c756f9 100644 --- a/src/bin/editor/edi_editor.c +++ b/src/bin/editor/edi_editor.c @@ -24,7 +24,7 @@ static Edi_Color EDI_COLOR_FOREGROUND = ""; static Edi_Color EDI_COLOR_COMMENT = ""; -//static Edi_Color EDI_COLOR_STRING = ""; +static Edi_Color EDI_COLOR_STRING = ""; static Edi_Color EDI_COLOR_NUMBER = "";// font_weight=Bold"; static Edi_Color EDI_COLOR_BRACE = ""; static Edi_Color EDI_COLOR_TYPE = ""; @@ -411,7 +411,10 @@ _clang_load_highlighting(const char *path, Edi_Editor *editor) } break; case CXToken_Literal: - color = EDI_COLOR_NUMBER; + if (cursors[i].kind == CXCursor_StringLiteral || cursors[i].kind == CXCursor_CharacterLiteral) + color = EDI_COLOR_STRING; + else + color = EDI_COLOR_NUMBER; break; case CXToken_Comment: color = EDI_COLOR_COMMENT; From 227c883b65d994c0ccfdabdfd0d5ccc246d5c4bb Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Thu, 13 Nov 2014 21:51:23 +0000 Subject: [PATCH 29/36] A little more markup to the diff example with character add/rem/change highlighting --- elm_code/bin/elm_code_test_main.c | 4 ++++ elm_code/lib/elm_code_common.h | 5 +++++ elm_code/lib/elm_code_widget.c | 15 +++++++++++---- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/elm_code/bin/elm_code_test_main.c b/elm_code/bin/elm_code_test_main.c index 40f73bf..33ab70c 100644 --- a/elm_code/bin/elm_code_test_main.c +++ b/elm_code/bin/elm_code_test_main.c @@ -71,7 +71,9 @@ _elm_code_test_diff_setup(Evas_Object *parent) elm_code_file_line_append(code->file, "unchanged"); elm_code_file_line_status_set(code->file, 4, ELM_CODE_STATUS_TYPE_REMOVED); + elm_code_file_line_token_add(code->file, 4, 1, 7, ELM_CODE_TOKEN_TYPE_REMOVED); elm_code_file_line_status_set(code->file, 5, ELM_CODE_STATUS_TYPE_CHANGED); + elm_code_file_line_token_add(code->file, 5, 1, 5, ELM_CODE_TOKEN_TYPE_REMOVED); 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); @@ -90,7 +92,9 @@ _elm_code_test_diff_setup(Evas_Object *parent) elm_code_file_line_append(code->file, "unchanged"); elm_code_file_line_status_set(code->file, 2, ELM_CODE_STATUS_TYPE_ADDED); + elm_code_file_line_token_add(code->file, 2, 1, 5, ELM_CODE_TOKEN_TYPE_ADDED); elm_code_file_line_status_set(code->file, 5, ELM_CODE_STATUS_TYPE_CHANGED); + elm_code_file_line_token_add(code->file, 5, 7, 7, ELM_CODE_TOKEN_TYPE_ADDED); 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); diff --git a/elm_code/lib/elm_code_common.h b/elm_code/lib/elm_code_common.h index e19a6b3..3e39c7b 100644 --- a/elm_code/lib/elm_code_common.h +++ b/elm_code/lib/elm_code_common.h @@ -23,6 +23,11 @@ typedef enum { ELM_CODE_TOKEN_TYPE_DEFAULT = ELM_CODE_STATUS_TYPE_COUNT, ELM_CODE_TOKEN_TYPE_COMMENT, + + ELM_CODE_TOKEN_TYPE_ADDED, + ELM_CODE_TOKEN_TYPE_REMOVED, + ELM_CODE_TOKEN_TYPE_CHANGED, + ELM_CODE_TOKEN_TYPE_COUNT } Elm_Code_Token_Type; diff --git a/elm_code/lib/elm_code_widget.c b/elm_code/lib/elm_code_widget.c index 011afdb..ce7eb86 100644 --- a/elm_code/lib/elm_code_widget.c +++ b/elm_code/lib/elm_code_widget.c @@ -152,16 +152,16 @@ EAPI Evas_Object *elm_code_widget_add(Evas_Object *parent, Elm_Code *code) // setup status colors evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_DEFAULT, - 54, 54, 54, 255); + 36, 36, 36, 255); evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_ERROR, 205, 54, 54, 255); evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_ADDED, - 54, 125, 54, 255); + 36, 96, 36, 255); evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_REMOVED, - 125, 54, 54, 255); + 96, 36, 36, 255); evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_CHANGED, - 54, 54, 125, 255); + 36, 36, 96, 255); // setup token colors evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_TOKEN_TYPE_DEFAULT, @@ -169,6 +169,13 @@ EAPI Evas_Object *elm_code_widget_add(Evas_Object *parent, Elm_Code *code) evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_TOKEN_TYPE_COMMENT, 54, 205, 255, 255); + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_TOKEN_TYPE_ADDED, + 54, 255, 54, 255); + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_TOKEN_TYPE_REMOVED, + 255, 54, 54, 255); + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_TOKEN_TYPE_CHANGED, + 54, 54, 255, 255); + evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _elm_code_widget_resize_cb, code); eo_do(o,eo_event_callback_add(&ELM_CODE_EVENT_LINE_SET_DONE, _elm_code_widget_line_cb, code)); From 5fc5e3abad79fb4bb6cac3a685e258f9ed794e40 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Thu, 13 Nov 2014 23:26:30 +0000 Subject: [PATCH 30/36] Refactor the widget token parsing so we can put it under test. Add simple test that demonstrates tokens split by space. --- elm_code/lib/elm_code_widget.c | 39 ++++++++++++++---------- elm_code/lib/elm_code_widget.h | 1 + elm_code/tests/Makefile.am | 1 + elm_code/tests/elm_code_suite.c | 1 + elm_code/tests/elm_code_suite.h | 1 + elm_code/tests/elm_code_test_widget.c | 44 +++++++++++++++++++++++++++ 6 files changed, 71 insertions(+), 16 deletions(-) create mode 100644 elm_code/tests/elm_code_test_widget.c diff --git a/elm_code/lib/elm_code_widget.c b/elm_code/lib/elm_code_widget.c index ce7eb86..32e00de 100644 --- a/elm_code/lib/elm_code_widget.c +++ b/elm_code/lib/elm_code_widget.c @@ -31,14 +31,34 @@ static void _elm_code_widget_fill_line_token(Evas_Textgrid_Cell *cells, int coun } } -static void _elm_code_widget_fill_line(Evas_Object *o, Evas_Textgrid_Cell *cells, Elm_Code_Line *line) +EAPI void elm_code_widget_fill_line_tokens(Evas_Textgrid_Cell *cells, int count, Elm_Code_Line *line) { Eina_List *item; Elm_Code_Token *token; + int start, length; + start = 1; + length = strlen(line->content); + + EINA_LIST_FOREACH(line->tokens, item, token) + { + + _elm_code_widget_fill_line_token(cells, count, start, token->start, ELM_CODE_TOKEN_TYPE_DEFAULT); + + // TODO handle a token starting before the previous finishes + _elm_code_widget_fill_line_token(cells, count, token->start, token->end, token->type); + + start = token->end + 1; + } + + _elm_code_widget_fill_line_token(cells, count, start, length, ELM_CODE_TOKEN_TYPE_DEFAULT); +} + +static void _elm_code_widget_fill_line(Evas_Object *o, Evas_Textgrid_Cell *cells, Elm_Code_Line *line) +{ char *chr; unsigned int length, x; - int w, start; + int w; if (!_elm_code_widget_resize(o)) return; @@ -60,20 +80,7 @@ static void _elm_code_widget_fill_line(Evas_Object *o, Evas_Textgrid_Cell *cells cells[x].bg = line->status; } - start = 1; - - EINA_LIST_FOREACH(line->tokens, item, token) - { - - _elm_code_widget_fill_line_token(cells, w, start, token->start, ELM_CODE_TOKEN_TYPE_DEFAULT); - - // TODO handle a token starting before the previous finishes - _elm_code_widget_fill_line_token(cells, w, token->start, token->end, token->type); - - start = token->end + 1; - } - - _elm_code_widget_fill_line_token(cells, w, start, length, ELM_CODE_TOKEN_TYPE_DEFAULT); + elm_code_widget_fill_line_tokens(cells, w, line); evas_object_textgrid_update_add(o, 0, line->number - 1, w, 1); } diff --git a/elm_code/lib/elm_code_widget.h b/elm_code/lib/elm_code_widget.h index dda5df8..8c2bf77 100644 --- a/elm_code/lib/elm_code_widget.h +++ b/elm_code/lib/elm_code_widget.h @@ -27,6 +27,7 @@ extern "C" { EAPI Evas_Object *elm_code_widget_add(Evas_Object *parent, Elm_Code *code); EAPI void elm_code_widget_fill(Evas_Object *o, Elm_Code *code); +EAPI void elm_code_widget_fill_line_tokens(Evas_Textgrid_Cell *cells, int count, Elm_Code_Line *line); /** * @} diff --git a/elm_code/tests/Makefile.am b/elm_code/tests/Makefile.am index aa71521..75ae85c 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_widget.c \ elm_code_suite.c elm_code_suite_CPPFLAGS = -I$(top_builddir)/elm_code/lib/ \ diff --git a/elm_code/tests/elm_code_suite.c b/elm_code/tests/elm_code_suite.c index 1f52521..1d9763b 100644 --- a/elm_code/tests/elm_code_suite.c +++ b/elm_code/tests/elm_code_suite.c @@ -15,6 +15,7 @@ static const struct { } tests[] = { { "file_load", elm_code_file_test_load }, { "file_memory", elm_code_file_test_memory }, + { "widget", elm_code_test_widget }, { "basic", elm_code_test_basic }, }; diff --git a/elm_code/tests/elm_code_suite.h b/elm_code/tests/elm_code_suite.h index b9d1bdf..bc2cc89 100644 --- a/elm_code/tests/elm_code_suite.h +++ b/elm_code/tests/elm_code_suite.h @@ -7,6 +7,7 @@ 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); #endif /* _EDLM_CODE_SUITE_H */ diff --git a/elm_code/tests/elm_code_test_widget.c b/elm_code/tests/elm_code_test_widget.c new file mode 100644 index 0000000..77bedd1 --- /dev/null +++ b/elm_code/tests/elm_code_test_widget.c @@ -0,0 +1,44 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "elm_code_suite.h" + +static void _assert_cell_type(Evas_Textgrid_Cell cell, Elm_Code_Token_Type type) +{ + ck_assert(cell.fg == type); +} + +START_TEST (elm_code_widget_token_render_simple_test) +{ + Elm_Code_File *file; + Elm_Code_Line *line; + int length; + + Evas_Textgrid_Cell cells[25]; + + file = elm_code_file_new(); + elm_code_file_line_append(file, "some \"test content\", 45"); + line = elm_code_file_line_get(file, 1); + length = strlen(line->content); + + elm_code_file_line_token_add(file, 1, 6+1, 18+1, ELM_CODE_TOKEN_TYPE_COMMENT); + elm_code_file_line_token_add(file, 1, 22+1, 23+1, ELM_CODE_TOKEN_TYPE_COMMENT); + + elm_code_widget_fill_line_tokens(cells, length, line); + _assert_cell_type(cells[0], ELM_CODE_TOKEN_TYPE_DEFAULT); + _assert_cell_type(cells[3], ELM_CODE_TOKEN_TYPE_DEFAULT); + _assert_cell_type(cells[5], ELM_CODE_TOKEN_TYPE_DEFAULT); + _assert_cell_type(cells[15], ELM_CODE_TOKEN_TYPE_COMMENT); + _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); +} +END_TEST + +void elm_code_test_widget(TCase *tc) +{ + tcase_add_test(tc, elm_code_widget_token_render_simple_test); +} + From d6da31acf3460c88463b78265c372cda67498406 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sun, 16 Nov 2014 23:52:41 +0000 Subject: [PATCH 31/36] Add parse hooks for lines and files within elm_code. This required changing the load order so file opens would read the elm_code->parsers setup. This makes for a better setup anyhow --- elm_code/bin/elm_code_test_main.c | 9 ++- elm_code/lib/Elm_Code.h | 7 ++- elm_code/lib/Makefile.am | 2 + elm_code/lib/elm_code.c | 14 +++-- elm_code/lib/elm_code_common.h | 7 ++- elm_code/lib/elm_code_file.c | 21 ++++--- elm_code/lib/elm_code_file.h | 4 +- elm_code/lib/elm_code_parse.c | 47 +++++++++++++++ elm_code/lib/elm_code_parse.h | 49 ++++++++++++++++ elm_code/tests/Makefile.am | 1 + elm_code/tests/elm_code_file_test_load.c | 20 +++++-- elm_code/tests/elm_code_file_test_memory.c | 12 ++-- elm_code/tests/elm_code_suite.c | 3 +- elm_code/tests/elm_code_suite.h | 3 +- elm_code/tests/elm_code_test_basic.c | 5 +- elm_code/tests/elm_code_test_parse.c | 68 ++++++++++++++++++++++ elm_code/tests/elm_code_test_widget.c | 6 +- src/bin/edi_logpanel.c | 3 +- 18 files changed, 243 insertions(+), 38 deletions(-) create mode 100644 elm_code/lib/elm_code_parse.c create mode 100644 elm_code/lib/elm_code_parse.h create mode 100644 elm_code/tests/elm_code_test_parse.c 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); From 5a7f736d9556fdddb4a20dc855ecd1ee15c816d6 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Tue, 18 Nov 2014 20:56:47 +0000 Subject: [PATCH 32/36] Fix crash when appending a line off and the body is already larger than the viewport --- elm_code/lib/elm_code_widget.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/elm_code/lib/elm_code_widget.c b/elm_code/lib/elm_code_widget.c index 32e00de..ba096e4 100644 --- a/elm_code/lib/elm_code_widget.c +++ b/elm_code/lib/elm_code_widget.c @@ -111,12 +111,18 @@ _elm_code_widget_line_cb(void *data EINA_UNUSED, Eo *obj, { Elm_Code_Line *line; Evas_Object *o; + int h; Evas_Textgrid_Cell *cells; line = (Elm_Code_Line *)event_info; o = (Evas_Object *)obj; + evas_object_textgrid_size_get(o, NULL, &h); + + if (line->number > (unsigned int) h) + return EINA_TRUE; + cells = evas_object_textgrid_cellrow_get(o, line->number - 1); _elm_code_widget_fill_line(o, cells, line); From a82431c627ee2f2bf193ec924b637401bf230073 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Tue, 18 Nov 2014 21:11:10 +0000 Subject: [PATCH 33/36] Add tests PASSED and FAILED to elm_code statuses and the widget rendering. Use this in EDI to add a test summarising panel. Tests are executed in verbose mode so we can list all the tests that have been run - can summarise later if we wish... --- elm_code/lib/Elm_Code.h | 1 + elm_code/lib/elm_code_common.h | 3 + elm_code/lib/elm_code_file.c | 15 +++++ elm_code/lib/elm_code_file.h | 2 + elm_code/lib/elm_code_widget.c | 5 ++ src/bin/edi_consolepanel.c | 115 +++++++++++++++++++++++++++++++++ src/bin/edi_consolepanel.h | 4 ++ src/bin/edi_main.c | 26 +++++++- src/lib/edi_builder.c | 2 +- 9 files changed, 170 insertions(+), 3 deletions(-) diff --git a/elm_code/lib/Elm_Code.h b/elm_code/lib/Elm_Code.h index 3ed59fb..eadf59d 100644 --- a/elm_code/lib/Elm_Code.h +++ b/elm_code/lib/Elm_Code.h @@ -7,6 +7,7 @@ #include #include +#include #include #ifdef EAPI diff --git a/elm_code/lib/elm_code_common.h b/elm_code/lib/elm_code_common.h index 3dc00ed..79f5d6c 100644 --- a/elm_code/lib/elm_code_common.h +++ b/elm_code/lib/elm_code_common.h @@ -17,6 +17,9 @@ typedef enum { ELM_CODE_STATUS_TYPE_REMOVED, ELM_CODE_STATUS_TYPE_CHANGED, + ELM_CODE_STATUS_TYPE_PASSED, + ELM_CODE_STATUS_TYPE_FAILED, + ELM_CODE_STATUS_TYPE_COUNT } Elm_Code_Status_Type; diff --git a/elm_code/lib/elm_code_file.c b/elm_code/lib/elm_code_file.c index 07ae9e2..e2d9daa 100644 --- a/elm_code/lib/elm_code_file.c +++ b/elm_code/lib/elm_code_file.c @@ -119,6 +119,21 @@ EAPI const char *elm_code_file_path_get(Elm_Code_File *file) return eina_file_filename_get(file->file); } +EAPI void elm_code_file_clear(Elm_Code_File *file) +{ + Elm_Code_Line *l; + + EINA_LIST_FREE(file->lines, l) + { + if (l->content) + free(l->content); + free(l); + } + + if (file->parent) + elm_code_callback_fire(file->parent, &ELM_CODE_EVENT_FILE_LOAD_DONE, file); +} + EAPI unsigned int elm_code_file_lines_get(Elm_Code_File *file) { return eina_list_count(file->lines); diff --git a/elm_code/lib/elm_code_file.h b/elm_code/lib/elm_code_file.h index 19a4725..c3ebfb9 100644 --- a/elm_code/lib/elm_code_file.h +++ b/elm_code/lib/elm_code_file.h @@ -76,6 +76,8 @@ EAPI const char *elm_code_file_path_get(Elm_Code_File *file); * */ +EAPI void elm_code_file_clear(Elm_Code_File *file); + EAPI unsigned int elm_code_file_lines_get(Elm_Code_File *file); EAPI void elm_code_file_line_append(Elm_Code_File *file, const char *line); diff --git a/elm_code/lib/elm_code_widget.c b/elm_code/lib/elm_code_widget.c index ba096e4..e555468 100644 --- a/elm_code/lib/elm_code_widget.c +++ b/elm_code/lib/elm_code_widget.c @@ -176,6 +176,11 @@ EAPI Evas_Object *elm_code_widget_add(Evas_Object *parent, Elm_Code *code) evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_CHANGED, 36, 36, 96, 255); + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_PASSED, + 54, 96, 54, 255); + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_FAILED, + 96, 54, 54, 255); + // setup token colors evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_TOKEN_TYPE_DEFAULT, 205, 205, 205, 255); diff --git a/src/bin/edi_consolepanel.c b/src/bin/edi_consolepanel.c index 20fe7c1..f790d58 100644 --- a/src/bin/edi_consolepanel.c +++ b/src/bin/edi_consolepanel.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -18,6 +19,13 @@ static Evas_Object *_console_box; static const char *_current_dir = NULL; +static int _edi_test_count; +static int _edi_test_pass; +static int _edi_test_fail; + +static Elm_Code *_edi_test_code; +static void _edi_test_line_callback(const char *content); + static const char *_edi_consolepanel_icon_for_line(const char *line) { if (strstr(line, " error:") != NULL) @@ -153,6 +161,8 @@ static void _edi_consolepanel_append_line_type(const char *line, Eina_Bool err) elm_box_pack_end(_console_box, box); _edi_consolepanel_scroll_to_bottom(); + + _edi_test_line_callback(line); } void edi_consolepanel_append_line(const char *line) @@ -168,6 +178,11 @@ void edi_consolepanel_append_error_line(const char *line) void edi_consolepanel_clear() { elm_box_clear(_console_box); + + elm_code_file_clear(_edi_test_code->file); + _edi_test_count = 0; + _edi_test_pass = 0; + _edi_test_fail = 0; } static Eina_Bool @@ -196,6 +211,87 @@ _exe_error(void *d EINA_UNUSED, int t EINA_UNUSED, void *event_info) return ECORE_CALLBACK_RENEW; } +static void _edi_test_append(const char *content, Elm_Code_Status_Type type) +{ + elm_code_file_line_append(_edi_test_code->file, content); + elm_code_file_line_status_set(_edi_test_code->file, elm_code_file_lines_get(_edi_test_code->file), type); +} + +static void _edi_test_line_parse_suite(const char *path) +{ + Eina_File *file; + Eina_File_Line *line; + Eina_Iterator *it; + char logfile[PATH_MAX], *tmp; + int pathlength; + Elm_Code_Status_Type status; + + pathlength = strlen(path); + snprintf(logfile, pathlength + 4 + 1, "%s.log", path); + + file = eina_file_open(logfile, EINA_FALSE); + + it = eina_file_map_lines(file); + EINA_ITERATOR_FOREACH(it, line) + { + status = ELM_CODE_STATUS_TYPE_DEFAULT; + tmp = malloc(line->length + 1); + strncpy(tmp, line->start, line->length); + tmp[line->length] = 0; + + if (strstr(tmp, ":P:")) + status = ELM_CODE_STATUS_TYPE_PASSED; + else if (strstr(tmp, ":F:")) + status = ELM_CODE_STATUS_TYPE_FAILED; + + _edi_test_append(tmp, status); + free(tmp); + } + eina_iterator_free(it); +} + +static void _edi_test_line_parse_suite_pass_line(const char *line) +{ + _edi_test_line_parse_suite(line); + _edi_test_append("Suite passed", ELM_CODE_STATUS_TYPE_DEFAULT); +} + +static void _edi_test_line_parse_suite_fail_line(const char *line) +{ + _edi_test_line_parse_suite(line); + _edi_test_append("Suite failed", ELM_CODE_STATUS_TYPE_DEFAULT); +} + +static void _edi_test_line_parse_summary_line(const char *line) +{ + _edi_test_append(line, ELM_CODE_STATUS_TYPE_DEFAULT); +} + +static void _edi_test_line_callback(const char *content) +{ + if (!content) + return; + + if (content[0] == '#') + { + _edi_test_line_parse_summary_line(content + 2); + return; + } + + if (!strncmp(content, "PASS:", 5)) + { + _edi_test_count++; + _edi_test_pass++; + _edi_test_line_parse_suite_pass_line(content + 6); + } + else if (!strncmp(content, "FAIL:", 5)) + { + _edi_test_count++; + _edi_test_fail++; + _edi_test_line_parse_suite_fail_line(content + 6); + } +} + void edi_consolepanel_add(Evas_Object *parent) { Evas_Object *scroll, *vbx; @@ -217,3 +313,22 @@ void edi_consolepanel_add(Evas_Object *parent) ecore_event_handler_add(ECORE_EXE_EVENT_DATA, _exe_data, NULL); ecore_event_handler_add(ECORE_EXE_EVENT_ERROR, _exe_error, NULL); } + +void edi_testpanel_add(Evas_Object *parent) +{ + Elm_Code *code; + Evas_Object *widget; + + code = elm_code_create(); + _edi_test_code = code; + 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); + evas_object_show(widget); + + elm_object_content_set(parent, widget); +} + diff --git a/src/bin/edi_consolepanel.h b/src/bin/edi_consolepanel.h index bd51a8b..37cf1fc 100644 --- a/src/bin/edi_consolepanel.h +++ b/src/bin/edi_consolepanel.h @@ -38,6 +38,10 @@ EAPI void edi_consolepanel_add(Evas_Object *parent); */ EAPI void edi_consolepanel_show(); +EAPI void edi_testpanel_add(Evas_Object *parent); + +EAPI void edi_testpanel_show(); + /** * @} */ diff --git a/src/bin/edi_main.c b/src/bin/edi_main.c index b475512..07c9f03 100644 --- a/src/bin/edi_main.c +++ b/src/bin/edi_main.c @@ -23,7 +23,7 @@ #define COPYRIGHT "Copyright © 2014 Andy Williams and various contributors (see AUTHORS)." -static Evas_Object *_edi_filepanel, *_edi_logpanel, *_edi_consolepanel; +static Evas_Object *_edi_filepanel, *_edi_logpanel, *_edi_consolepanel, *_edi_testpanel; static Evas_Object *_edi_main_win, *_edi_new_popup, *_edi_goto_popup; static void @@ -58,6 +58,11 @@ void edi_consolepanel_show() elm_panel_hidden_set(_edi_consolepanel, EINA_FALSE); } +void edi_testpanel_show() +{ + elm_panel_hidden_set(_edi_testpanel, EINA_FALSE); +} + static Evas_Object * edi_content_setup(Evas_Object *win, const char *path) { @@ -69,6 +74,7 @@ edi_content_setup(Evas_Object *win, const char *path) _edi_filepanel = elm_panel_add(win); _edi_logpanel = elm_panel_add(win); _edi_consolepanel = elm_panel_add(win); + _edi_testpanel = elm_panel_add(win); // add main content content_out = elm_box_add(win); @@ -119,6 +125,7 @@ edi_content_setup(Evas_Object *win, const char *path) elm_toolbar_item_append(tb, NULL, "Logs", _edi_toggle_panel, _edi_logpanel); elm_toolbar_item_append(tb, NULL, "Console", _edi_toggle_panel, _edi_consolepanel); + elm_toolbar_item_append(tb, NULL, "Tests", _edi_toggle_panel, _edi_testpanel); elm_panel_orient_set(_edi_logpanel, ELM_PANEL_ORIENT_BOTTOM); evas_object_size_hint_weight_set(_edi_logpanel, EVAS_HINT_EXPAND, 0.15); @@ -142,6 +149,17 @@ edi_content_setup(Evas_Object *win, const char *path) elm_table_pack(panes, _edi_consolepanel, 0, 4, 6, 1); evas_object_show(_edi_consolepanel); + elm_panel_orient_set(_edi_testpanel, ELM_PANEL_ORIENT_BOTTOM); + evas_object_size_hint_weight_set(_edi_testpanel, EVAS_HINT_EXPAND, 0.15); + evas_object_size_hint_align_set(_edi_testpanel, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(_edi_testpanel); + + elm_panel_hidden_set(_edi_testpanel, EINA_FALSE); + elm_panel_hidden_set(_edi_testpanel, EINA_TRUE); + edi_testpanel_add(_edi_testpanel); + elm_table_pack(panes, _edi_testpanel, 0, 4, 6, 1); + evas_object_show(_edi_testpanel); + evas_object_show(panes); return panes; } @@ -331,7 +349,11 @@ static void _tb_test_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) { if (_edi_build_prep(obj)) - edi_builder_test(); + { + elm_panel_hidden_set(_edi_consolepanel, EINA_TRUE); + edi_testpanel_show(); + edi_builder_test(); + } } /* static void diff --git a/src/lib/edi_builder.c b/src/lib/edi_builder.c index 017e63f..eebeedc 100644 --- a/src/lib/edi_builder.c +++ b/src/lib/edi_builder.c @@ -54,7 +54,7 @@ EAPI void edi_builder_test(void) { chdir(edi_project_get()); - ecore_exe_pipe_run("make check", ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | + ecore_exe_pipe_run("CK_VERBOSITY=verbose make check", ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR, NULL); } From e03730b9131c934bd00fba40637b31b2c9bf483b Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Tue, 18 Nov 2014 21:35:18 +0000 Subject: [PATCH 34/36] Fix potential crash when going to the line of a large file. It will not work first time, but that's a seperate issue --- src/bin/mainview/edi_mainview.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/mainview/edi_mainview.c b/src/bin/mainview/edi_mainview.c index f673bf7..4b513e5 100644 --- a/src/bin/mainview/edi_mainview.c +++ b/src/bin/mainview/edi_mainview.c @@ -559,7 +559,7 @@ edi_mainview_goto(int line) it = elm_naviframe_top_item_get(nf); content = elm_object_item_content_get(it); editor = (Edi_Editor *)evas_object_data_get(content, "editor"); - if (!content || line <= 0) + if (!content || !editor || line <= 0) return; _tb = elm_entry_textblock_get(editor->entry); From 5229d2107c4dea971a36739008aa166ddc3789c2 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Tue, 18 Nov 2014 21:37:58 +0000 Subject: [PATCH 35/36] Improve displaying of test panel when running test Only display desired panel - others can be opened manually --- src/bin/edi_main.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/bin/edi_main.c b/src/bin/edi_main.c index 07c9f03..ebc2a2b 100644 --- a/src/bin/edi_main.c +++ b/src/bin/edi_main.c @@ -322,12 +322,15 @@ _tb_goto_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUS } static Eina_Bool -_edi_build_prep(Evas_Object *button) +_edi_build_prep(Evas_Object *button, Eina_Bool test) { elm_toolbar_item_selected_set(elm_toolbar_selected_item_get(button), EINA_FALSE); edi_consolepanel_clear(); - edi_consolepanel_show(); + if (test) + edi_testpanel_show(); + else + edi_consolepanel_show(); if (!edi_builder_can_build()) { @@ -341,32 +344,28 @@ _edi_build_prep(Evas_Object *button) static void _tb_build_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) { - if (_edi_build_prep(obj)) + if (_edi_build_prep(obj, EINA_FALSE)) edi_builder_build(); } static void _tb_test_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) { - if (_edi_build_prep(obj)) - { - elm_panel_hidden_set(_edi_consolepanel, EINA_TRUE); - edi_testpanel_show(); - edi_builder_test(); - } + if (_edi_build_prep(obj, EINA_TRUE)) + edi_builder_test(); } /* static void _tb_run_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) { - if (_edi_build_prep(obj)) + if (_edi_build_prep(obj, EINA_FALSE)) edi_builder_run(); } */ static void _tb_clean_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) { - if (_edi_build_prep(obj)) + if (_edi_build_prep(obj, EINA_FALSE)) edi_builder_clean(); } From 4748f81023defad7f4111e642a7e48566dceb313 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Tue, 18 Nov 2014 22:48:37 +0000 Subject: [PATCH 36/36] Add some text mode icons to markup the lines for now --- elm_code/lib/elm_code_widget.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/elm_code/lib/elm_code_widget.c b/elm_code/lib/elm_code_widget.c index e555468..9d44163 100644 --- a/elm_code/lib/elm_code_widget.c +++ b/elm_code/lib/elm_code_widget.c @@ -9,6 +9,20 @@ #include "elm_code_private.h" +Eina_Unicode status_icons[] = { + ' ', + '!', + + '+', + '-', + ' ', + + 0x2713, + 0x2717, + + 0 +}; + static Eina_Bool _elm_code_widget_resize(Evas_Object *o) { int w, h, cw, ch; @@ -25,7 +39,7 @@ static void _elm_code_widget_fill_line_token(Evas_Textgrid_Cell *cells, int coun { int x; - for (x = start - 1; x < end && x < count; x++) + for (x = start; x <= end && x < count; x++) { cells[x].fg = type; } @@ -66,8 +80,13 @@ static void _elm_code_widget_fill_line(Evas_Object *o, Evas_Textgrid_Cell *cells length = strlen(line->content); evas_object_textgrid_size_get(o, &w, NULL); + cells[0].codepoint = status_icons[line->status]; + cells[0].bold = 1; + cells[0].fg = ELM_CODE_TOKEN_TYPE_DEFAULT; + cells[0].bg = line->status; + chr = (char *)line->content; - for (x = 0; x < (unsigned int) w && x < length; x++) + for (x = 1; x < (unsigned int) w && x <= length; x++) { cells[x].codepoint = *chr; cells[x].bg = line->status;