Merge branch devs/ajwillia-ms/elm_code

This commit is contained in:
Andy Williams 2014-11-18 23:04:19 +00:00
commit 86856485bd
37 changed files with 2180 additions and 42 deletions

9
.gitignore vendored
View File

@ -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,14 @@ 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/bin/elm_code_test
/elm_code/tests/elm_code_suite
/elm_code/tests/elm_code_suite.*
/elm_code/tests/test-suite.log
/elm_code/tests/check-results.xml

View File

@ -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

View File

@ -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
])
@ -101,6 +102,10 @@ src/Makefile
src/bin/Makefile
src/lib/Makefile
src/tests/Makefile
elm_code/Makefile
elm_code/lib/Makefile
elm_code/bin/Makefile
elm_code/tests/Makefile
doc/edi.1
])
AC_OUTPUT

4
elm_code/Makefile.am Normal file
View File

@ -0,0 +1,4 @@
MAINTAINERCLEANFILES = Makefile.in
SUBDIRS = lib bin tests

20
elm_code/bin/Makefile.am Normal file
View File

@ -0,0 +1,20 @@
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/ \
-DEFL_BETA_API_SUPPORT \
@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

View File

@ -0,0 +1,205 @@
#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 <Ecore_Getopt.h>
#include <Elementary.h>
#include "gettext.h"
#include <Elm_Code.h>
#include "elm_code_test_private.h"
#define COPYRIGHT "Copyright © 2014 andy <andy@andywilliams.me> 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_welcome_setup(Evas_Object *parent)
{
Elm_Code *code;
Evas_Object *widget;
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);
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 ***");
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);
return widget;
}
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(code);
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_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);
evas_object_show(widget);
elm_box_pack_end(hbox, widget);
// right side of diff
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");
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_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);
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;
}
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()

View File

@ -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

280
elm_code/bin/gettext.h Normal file
View File

@ -0,0 +1,280 @@
/* Convenience header for conditional use of GNU <libintl.h>.
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 <libintl.h>
/* 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 <locale.h> a NOP. We don't include <libintl.h>
as well because people using "gettext.h" will not include <libintl.h>,
and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
is OK. */
#if defined(__sun)
# include <locale.h>
#endif
/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
<libintl.h>, which chokes if dcgettext is defined as a macro. So include
it now, to make later inclusions of <libintl.h> a NOP. */
#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
# include <cstdlib>
# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
# include <libintl.h>
# 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 <string.h>
#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
(((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
/* || __STDC_VERSION__ >= 199901L */ )
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
#include <stdlib.h>
#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 */

135
elm_code/lib/Elm_Code.h Normal file
View File

@ -0,0 +1,135 @@
#ifndef ELM_CODE_H_
# define ELM_CODE_H_
#include <Elementary.h>
#include <Eo.h>
#include <Eina.h>
#include <elm_code_common.h>
#include <elm_code_file.h>
#include <elm_code_parse.h>
#include <elm_code_widget.h>
#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 loading Elm Code widgets.
*/
/**
* @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);
/**
* Create a new Elm Code instance
*
* 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();
/**
* Free an Elm Code instance
*
* Releases the resources retained by the code instance and any files it references.
*/
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 Eo_Event_Description *signal, void *data);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ELM_CODE_H_ */

27
elm_code/lib/Makefile.am Normal file
View File

@ -0,0 +1,27 @@
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)\" \
-DEFL_BETA_API_SUPPORT \
@EFL_CFLAGS@ \
-DEFL_EFL_BUILD
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
libelm_code_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@

112
elm_code/lib/elm_code.c Normal file
View File

@ -0,0 +1,112 @@
#ifdef HAVE_CONFIG
# include "config.h"
#endif
#include <Eo.h>
#include "Elm_Code.h"
#include "elm_code_parse.h"
#include "elm_code_private.h"
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", "");
const Eo_Event_Description ELM_CODE_EVENT_FILE_LOAD_DONE =
EO_EVENT_DESCRIPTION("file, load,done", "");
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;
}
EAPI Elm_Code *
elm_code_create()
{
Elm_Code *ret;
ret = calloc(1, sizeof(Elm_Code));
return ret;
}
EAPI void
elm_code_free(Elm_Code *code)
{
Evas_Object *widget;
Elm_Code_Parser *parser;
if (code->file)
elm_code_file_free(code->file);
EINA_LIST_FREE(code->widgets, widget)
{
evas_object_hide(widget);
evas_object_del(widget);
}
EINA_LIST_FREE(code->parsers, parser)
{
free(parser);
}
free(code);
}
EAPI void
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(signal, data));
}
}

View File

@ -0,0 +1,67 @@
#ifndef ELM_CODE_COMMON_H_
# define ELM_CODE_COMMON_H_
#include <Eo.h>
#include <Eina.h>
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;
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_PASSED,
ELM_CODE_STATUS_TYPE_FAILED,
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_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;
#include "elm_code_file.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file
* @brief Common data structures and constants.
*/
struct _Elm_Code
{
Elm_Code_File *file;
Eina_List *widgets;
Eina_List *parsers;
};
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ELM_CODE_COMMON_H_ */

View File

@ -0,0 +1,200 @@
#ifdef HAVE_CONFIG
# include "config.h"
#endif
#include "Elm_Code.h"
#include "elm_code_file.h"
#include "elm_code_parse.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;
ecl->status = ELM_CODE_STATUS_TYPE_DEFAULT;
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);
if (file->parent)
{
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(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(Elm_Code *code, const char *path)
{
Elm_Code_File *ret;
Eina_File *file;
Eina_File_Line *line;
Eina_Iterator *it;
unsigned int lastindex;
ret = elm_code_file_new(code);
file = eina_file_open(path, EINA_FALSE);
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);
}
_elm_code_file_line_append_data(ret, line->start, line->length, lastindex = line->index);
}
eina_iterator_free(it);
if (ret->parent)
{
elm_code_parse_file(ret->parent, ret);
elm_code_callback_fire(ret->parent, &ELM_CODE_EVENT_FILE_LOAD_DONE, ret);
}
return ret;
}
EAPI void elm_code_file_free(Elm_Code_File *file)
{
Elm_Code_Line *l;
EINA_LIST_FREE(file->lines, l)
{
if (l->content)
free(l->content);
free(l);
}
free(file);
}
EAPI void elm_code_file_close(Elm_Code_File *file)
{
eina_file_close(file->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 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);
}
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 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 = elm_code_file_line_get(file, number);
if (!line)
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);
}
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);
}

View File

@ -0,0 +1,102 @@
#ifndef ELM_CODE_FILE_H_
# define ELM_CODE_FILE_H_
#include <Eina.h>
#include "elm_code_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file
* @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;
typedef struct _Elm_Code_File
{
void *parent;
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_new(Elm_Code *code);
EAPI Elm_Code_File *elm_code_file_open(Elm_Code *code, 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);
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 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);
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);
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);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ELM_CODE_FILE_H_ */

View File

@ -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);
}

View File

@ -0,0 +1,49 @@
#ifndef ELM_CODE_PARSE_H_
# define ELM_CODE_PARSE_H_
#include <Eina.h>
#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_ */

View File

@ -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

View File

@ -0,0 +1,224 @@
#ifdef HAVE_CONFIG
# include "config.h"
#endif
#include <Eo.h>
#include <Elementary.h>
#include "elm_code_widget.h"
#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;
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; x <= end && x < count; x++)
{
cells[x].fg = type;
}
}
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;
if (!_elm_code_widget_resize(o))
return;
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 = 1; 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;
}
elm_code_widget_fill_line_tokens(cells, w, line);
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);
cells = evas_object_textgrid_cellrow_get(o, y - 1);
_elm_code_widget_fill_line(o, cells, line);
}
}
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_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);
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)
{
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());
// setup status colors
evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_DEFAULT,
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,
36, 96, 36, 255);
evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_REMOVED,
96, 36, 36, 255);
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);
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));
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;
}

View File

@ -0,0 +1,40 @@
#ifndef ELM_CODE_WIDGET_H_
# define ELM_CODE_WIDGET_H_
#include <Eina.h>
#include <Evas.h>
#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);
EAPI void elm_code_widget_fill_line_tokens(Evas_Textgrid_Cell *cells, int count, Elm_Code_Line *line);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ELM_CODE_WIDGET_H_ */

View File

@ -0,0 +1,26 @@
if EFL_HAVE_TESTS
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_test_parse.c \
elm_code_test_widget.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/\" \
-DEFL_BETA_API_SUPPORT \
@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

View File

@ -0,0 +1,78 @@
#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;
Elm_Code *code;
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
START_TEST (elm_code_file_load_lines)
{
char *path = "elm_code/tests/testfile.txt";
Elm_Code_File *file;
Elm_Code *code;
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
START_TEST (elm_code_file_load_blank_lines)
{
char *path = "elm_code/tests/testfile-withblanks.txt";
Elm_Code_File *file;
Elm_Code *code;
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
START_TEST (elm_code_file_load_content)
{
char *path = "elm_code/tests/testfile.txt";
Elm_Code_File *file;
Elm_Code *code;
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
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);
}

View File

@ -0,0 +1,46 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "elm_code_suite.h"
START_TEST (elm_code_file_memory_lines)
{
Elm_Code_File *file;
Elm_Code *code;
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_free(code);
}
END_TEST
START_TEST (elm_code_file_memory_tokens)
{
Elm_Code_File *file;
Elm_Code_Line *line;
Elm_Code *code;
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_free(code);
}
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);
}

View File

@ -0,0 +1,126 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Ecore_Getopt.h>
#include "Elm_Code.h"
#include "elm_code_suite.h"
#define COPYRIGHT "Copyright © 2014 Andy Williams <andy@andyilliams.me> and various contributors (see AUTHORS)."
static const struct {
const char *name;
void (*build)(TCase *tc);
} tests[] = {
{ "file_load", elm_code_file_test_load },
{ "file_memory", elm_code_file_test_memory },
{ "parse", elm_code_test_parse },
{ "basic", elm_code_test_basic },
{ "widget", elm_code_test_widget },
};
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;
}

View File

@ -0,0 +1,14 @@
#ifndef _ELM_CODE_SUITE_H
#define _ELM_CODE_SUITE_H
#include <check.h>
#include <Elm_Code.h>
void elm_code_file_test_load(TCase *tc);
void elm_code_file_test_memory(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 */

View File

@ -0,0 +1,24 @@
#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 *code;
code = elm_code_create();
elm_code_file_open(code, path);
ck_assert(code);
elm_code_free(code);
}
END_TEST
void elm_code_test_basic(TCase *tc)
{
tcase_add_test(tc, elm_code_create_test);
}

View File

@ -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);
}

View File

@ -0,0 +1,46 @@
#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;
Elm_Code *code;
int length;
Evas_Textgrid_Cell cells[25];
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);
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_free(code);
}
END_TEST
void elm_code_test_widget(TCase *tc)
{
tcase_add_test(tc, elm_code_widget_token_render_simple_test);
}

View File

@ -0,0 +1,8 @@
line 1
line2
another link
double blank
8

View File

@ -0,0 +1,4 @@
line 1
line2
a third
another line

View File

@ -6,8 +6,9 @@ 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/ \
-DEFL_BETA_API_SUPPORT \
@EFL_CFLAGS@
edi_SOURCES = \
@ -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

View File

@ -6,6 +6,7 @@
#include <Eina.h>
#include <Ecore.h>
#include <Elm_Code.h>
#include <Elementary.h>
#include <Elementary_Cursor.h>
#include <regex.h>
@ -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);
}

View File

@ -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();
/**
* @}
*/

View File

@ -3,12 +3,14 @@
#endif
#include <Eina.h>
#include <Elm_Code.h>
#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,47 +21,39 @@ void print_cb(const Eina_Log_Domain *domain,
EINA_UNUSED void *data,
va_list args)
{
Evas_Object *txt;
unsigned int printed, buffer_len = 512;
unsigned int printed, line_count, buffer_len = 512;
char buffer [buffer_len];
printed = snprintf(buffer, buffer_len, "%s:%s:%s (%d): ",
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);
{
line_count = elm_code_file_lines_get(_elm_code->file);
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);
elm_code_file_line_status_set(_elm_code->file, line_count, ELM_CODE_STATUS_TYPE_ERROR);
}
}
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(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);
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);
}

View File

@ -23,7 +23,7 @@
#define COPYRIGHT "Copyright © 2014 Andy Williams <andy@andyilliams.me> 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;
}
@ -304,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())
{
@ -323,28 +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))
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();
}

View File

@ -24,7 +24,7 @@
static Edi_Color EDI_COLOR_FOREGROUND = "<color=#ffffff>";
static Edi_Color EDI_COLOR_COMMENT = "<color=#3399ff>";
//static Edi_Color EDI_COLOR_STRING = "<color=#ff5a35>";
static Edi_Color EDI_COLOR_STRING = "<color=#ff5a35>";
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>";
@ -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;

View File

@ -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 = \

View File

@ -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);
}