jackdanielz pushed a commit to branch master.

http://git.enlightenment.org/tools/exactness.git/commit/?id=a21c2f39cc885ac0ce5cc2f358b518f14baab893

commit a21c2f39cc885ac0ce5cc2f358b518f14baab893
Author: Daniel Zaoui <daniel.za...@samsung.com>
Date:   Wed Mar 23 14:41:47 2016 +0200

    Add an new executable to help on recordings maintenance
    
    An issue that currently happens in Exactness is that we don't have any
    way to debug the recordings.
    Only debug information can help us to figure out what data is stored
    inside the rec files.
    
    Three commands are available:
    - Clean: remove bad timestamp events and duplicate events
    - Add a delay: because of the first event is directly treated if no
    first timestamp is present, we need a way to fix recordings by adding
    them a delay before the first event.
    - List information: display the list of events, as vieet doesn't work at
    all. Really helpful to figure out bugs.
---
 src/bin/.gitignore         |   1 +
 src/bin/Makefile.am        |   9 +-
 src/bin/exactness_helper.c | 246 +++++++++++++++++++++++++++++++++++++++++++++
 src/lib/Makefile.am        |   2 +-
 src/lib/tsuite_evas_hook.c |   2 +-
 src/lib/tsuite_file_data.c |   2 +-
 src/lib/tsuite_file_data.h |  37 ++++++-
 7 files changed, 292 insertions(+), 7 deletions(-)

diff --git a/src/bin/.gitignore b/src/bin/.gitignore
index ac82ee4..cffebe9 100644
--- a/src/bin/.gitignore
+++ b/src/bin/.gitignore
@@ -1 +1,2 @@
 /exactness
+/exactness_helper
diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am
index 079a7f1..35ae159 100644
--- a/src/bin/Makefile.am
+++ b/src/bin/Makefile.am
@@ -1,6 +1,6 @@
 MAINTAINERCLEANFILES = Makefile.in
 
-bin_PROGRAMS = exactness
+bin_PROGRAMS = exactness exactness_helper
 
 exactness_SOURCES = \
                      exactness.c \
@@ -9,11 +9,18 @@ exactness_SOURCES = \
                      scheduler.c \
                      run_test.c
 
+exactness_helper_SOURCES = exactness_helper.c
+
 exactness_LDADD = \
                    @EFL_LIBS@
 
+exactness_helper_LDADD = \
+                   @EFL_LIBS@ ../lib/libexactness.la
+
 exactness_CFLAGS = \
                     @EFL_CFLAGS@ \
                     -I$(top_srcdir)/src/lib \
                     -DPACKAGE_LIBDIR=\"$(libdir)\" \
                     -DPACKAGE_DATADIR=\"$(datadir)\"
+
+exactness_helper_CFLAGS = @EFL_CFLAGS@ -I$(top_srcdir)/src/lib
diff --git a/src/bin/exactness_helper.c b/src/bin/exactness_helper.c
new file mode 100644
index 0000000..ab5cc03
--- /dev/null
+++ b/src/bin/exactness_helper.c
@@ -0,0 +1,246 @@
+#include <Ecore.h>
+#include <Ecore_Getopt.h>
+
+#include "tsuite_file_data.h"
+
+static const char *
+_event_name_get(const Variant_st *v)
+{
+   switch(tsuite_event_mapping_type_get(v->t.type))
+     {
+      case TSUITE_EVENT_MOUSE_IN: return "Mouse In";
+      case TSUITE_EVENT_MOUSE_OUT: return "Mouse Out";
+      case TSUITE_EVENT_MOUSE_DOWN: return "Mouse Down";
+      case TSUITE_EVENT_MOUSE_UP: return "Mouse Up";
+      case TSUITE_EVENT_MOUSE_MOVE: return "Mouse Move";
+      case TSUITE_EVENT_MOUSE_WHEEL: return "Mouse Wheel";
+      case TSUITE_EVENT_MULTI_DOWN: return "Multi Down";
+      case TSUITE_EVENT_MULTI_UP: return "Multi Up";
+      case TSUITE_EVENT_MULTI_MOVE: return "Multi Move";
+      case TSUITE_EVENT_KEY_DOWN: return "Key Down";
+      case TSUITE_EVENT_KEY_UP: return "Key Up";
+      case TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE: return "Key Down with Keycode";
+      case TSUITE_EVENT_KEY_UP_WITH_KEYCODE: return "Key Up with Keycode";
+      case TSUITE_EVENT_TAKE_SHOT: return "Take shot";
+      default: return NULL;
+     }
+}
+
+static int
+_event_struct_len_get(Tsuite_Event_Type type)
+{
+   switch(type)
+     {
+      case TSUITE_EVENT_MOUSE_IN: case TSUITE_EVENT_MOUSE_OUT: return 
sizeof(mouse_in_mouse_out);
+      case TSUITE_EVENT_MOUSE_DOWN: case TSUITE_EVENT_MOUSE_UP: return 
sizeof(mouse_down_mouse_up);
+      case TSUITE_EVENT_MOUSE_MOVE: return sizeof(mouse_move);
+      case TSUITE_EVENT_MOUSE_WHEEL: return sizeof(mouse_wheel);
+      case TSUITE_EVENT_MULTI_DOWN: case TSUITE_EVENT_MULTI_UP: return 
sizeof(multi_move);
+      case TSUITE_EVENT_MULTI_MOVE: return sizeof(multi_event);
+      case TSUITE_EVENT_KEY_DOWN: case TSUITE_EVENT_KEY_UP: return 
sizeof(key_down_key_up);
+      case TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE: case 
TSUITE_EVENT_KEY_UP_WITH_KEYCODE: return sizeof(key_down_key_up_with_keycode);
+      case TSUITE_EVENT_TAKE_SHOT: return sizeof(take_screenshot);
+      default: return 0;
+     }
+}
+
+static void
+_event_specific_info_get(const Variant_st *v, char output[1024])
+{
+   switch(tsuite_event_mapping_type_get(v->t.type))
+     {
+      case TSUITE_EVENT_MOUSE_DOWN:
+           {
+              mouse_down_mouse_up *t = v->data;
+              sprintf(output, "Button %d Flags %d", t->b, t->flags);
+              break;
+           }
+      case TSUITE_EVENT_MOUSE_UP:
+           {
+              mouse_down_mouse_up *t = v->data;
+              sprintf(output, "Button %d Flags %d", t->b, t->flags);
+              break;
+           }
+      case TSUITE_EVENT_MOUSE_MOVE:
+           {
+              mouse_move *t = v->data;
+              sprintf(output, "X %d Y %d", t->x, t->y);
+              break;
+           }
+      case TSUITE_EVENT_MOUSE_WHEEL:
+           {
+              mouse_wheel *t = v->data;
+              sprintf(output, "Direction %d Z %d", t->direction, t->z);
+              break;
+           }
+      case TSUITE_EVENT_MULTI_DOWN: case TSUITE_EVENT_MULTI_UP:
+           {
+              multi_event *t = v->data;
+              sprintf(output, "D %d X %d Y %d Rad %f RadX %f RadY %f Pres %f 
Ang %f FX %f FY %f Flags %d",
+                    t->d, t->x, t->y, t->rad, t->radx, t->rady, t->pres, 
t->ang, t->fx, t->fy, t->flags);
+              break;
+           }
+      case TSUITE_EVENT_MULTI_MOVE:
+           {
+              multi_move *t = v->data;
+              sprintf(output, "D %d X %d Y %d Rad %f RadX %f RadY %f Pres %f 
Ang %f FX %f FY %f",
+                    t->d, t->x, t->y, t->rad, t->radx, t->rady, t->pres, 
t->ang, t->fx, t->fy);
+              break;
+           }
+      case TSUITE_EVENT_KEY_UP: case TSUITE_EVENT_KEY_DOWN:
+           {
+              key_down_key_up *t = v->data;
+              sprintf(output, "Keyname %s Key %s String %s Compose %s",
+                    t->keyname, t->key, t->string, t->compose);
+              break;
+           }
+      case TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE: case 
TSUITE_EVENT_KEY_UP_WITH_KEYCODE:
+           {
+              key_down_key_up_with_keycode *t = v->data;
+              sprintf(output, "Keyname %s Key %s String %s Compose %s Keycode 
%d",
+                    t->keyname, t->key, t->string, t->compose, t->keycode);
+              break;
+           }
+      default:
+           {
+              output[0] = '\0';
+              break;
+           }
+     }
+}
+static const Ecore_Getopt optdesc = {
+  "exactness_helper",
+  "%prog [options] <rec file>",
+  NULL,
+  "(C) 2016 Enlightenment",
+  "BSD",
+  "Helper for Exactness",
+  0,
+  {
+    ECORE_GETOPT_STORE_USHORT('d', "delay", "Delay the given recording by a 
given time (in seconds)."),
+    ECORE_GETOPT_STORE_TRUE('c', "clean", "Clean the given recording from 
wrong events."),
+    ECORE_GETOPT_STORE_TRUE('l', "list", "List the events of the given 
recording"),
+
+    ECORE_GETOPT_LICENSE('L', "license"),
+    ECORE_GETOPT_COPYRIGHT('C', "copyright"),
+    ECORE_GETOPT_VERSION('V', "version"),
+    ECORE_GETOPT_HELP('h', "help"),
+    ECORE_GETOPT_SENTINEL
+  }
+};
+
+static Eina_Bool
+_is_hook_duplicate(const Variant_st *cur_v, const Variant_st *prev_v)
+{
+   if (!prev_v) return EINA_FALSE;
+   Tsuite_Event_Type cur_type = tsuite_event_mapping_type_get(cur_v->t.type);
+   Tsuite_Event_Type prev_type = tsuite_event_mapping_type_get(prev_v->t.type);
+   if (cur_type == prev_type &&
+         !memcmp(cur_v->data, prev_v->data, _event_struct_len_get(cur_type))) 
return EINA_TRUE;
+   return EINA_FALSE;
+}
+
+int
+main(int argc, char *argv[])
+{
+   const char *rec_file = NULL;
+   int ret = 0, args = 0;
+   unsigned short delay = 0;
+   Eina_Bool want_quit, clean = EINA_FALSE, list_get = EINA_FALSE;
+   Ecore_Getopt_Value values[] = {
+     ECORE_GETOPT_VALUE_USHORT(delay),
+     ECORE_GETOPT_VALUE_BOOL(clean),
+     ECORE_GETOPT_VALUE_BOOL(list_get),
+
+     ECORE_GETOPT_VALUE_BOOL(want_quit),
+     ECORE_GETOPT_VALUE_BOOL(want_quit),
+     ECORE_GETOPT_VALUE_BOOL(want_quit),
+     ECORE_GETOPT_VALUE_BOOL(want_quit),
+     ECORE_GETOPT_VALUE_NONE
+   };
+
+   ecore_init();
+   want_quit = EINA_FALSE;
+
+   args = ecore_getopt_parse(&optdesc, values, argc, argv);
+   if (args < 0)
+     {
+        fprintf(stderr, "Failed parsing arguments.\n");
+        ret = 1;
+        goto end;
+     }
+   else if (want_quit)
+     {
+        ret = 1;
+        goto end;
+     }
+   else if (args == argc)
+     {
+        fprintf(stderr, "Expected rec file as the last argument..\n");
+        ecore_getopt_help(stderr, &optdesc);
+        ret = 1;
+        goto end;
+     }
+
+   rec_file = argv[args];
+   Timer_Data td;
+   Lists_st *list = read_events(rec_file, &td);
+
+   if (clean)
+     {
+        Variant_st *v;
+        Eina_List *itr, *itr2;
+        EINA_LIST_FOREACH_SAFE(list->variant_list, itr, itr2, v)
+          {
+             if (!evt_time_get(0, v))
+                list->variant_list = eina_list_remove_list(list->variant_list, 
itr);
+             else
+               {
+                  if (_is_hook_duplicate(v, 
eina_list_data_get(eina_list_prev(itr))))
+                     list->variant_list = 
eina_list_remove_list(list->variant_list, itr);
+               }
+          }
+        if (!list->first_timestamp)
+          {
+             list->first_timestamp = evt_time_get(0, 
eina_list_data_get(list->variant_list));
+          }
+     }
+
+   if (delay)
+     {
+        delay *= 1000;
+
+        if (!list->first_timestamp)
+          {
+             list->first_timestamp = evt_time_get(0, 
eina_list_data_get(list->variant_list));
+          }
+        list->first_timestamp -= delay;
+     }
+
+   if (list_get)
+     {
+        Variant_st *v;
+        Eina_List *itr;
+        printf("First timestamp: ");
+        if (list->first_timestamp) printf("%u\n", list->first_timestamp);
+        else printf("undefined\n");
+        EINA_LIST_FOREACH(list->variant_list, itr, v)
+          {
+             char specific_output[1024];
+             unsigned int timestamp = evt_time_get(0, v);
+             if (!timestamp) printf("BAD_TIME: ");
+             else printf("%.3f: ", (list->first_timestamp ? timestamp - 
list->first_timestamp : timestamp) / 1000.0);
+             printf("%s", _event_name_get(v));
+             _event_specific_info_get(v, specific_output);
+             if (*specific_output) printf(" - %s", specific_output);
+             printf("\n");
+          }
+     }
+
+   write_events(rec_file, list);
+
+end:
+   ecore_shutdown();
+
+   return ret;
+}
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index b983abf..35b7e4d 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -18,7 +18,7 @@ libexactness_la_SOURCES = \
                          tsuite_evas_hook.c  \
                          tsuite_file_data.c
 
-libexactness_la_LDFLAGS = -module -avoid-version -rdynamic
+libexactness_la_LDFLAGS = -avoid-version -rdynamic
 libexactness_la_DEPENDENCIES = $(top_builddir)/config.h
 libexactness_la_LIBADD = @EFL_LIBS@
 libexactness_la_CFLAGS = @EFL_CFLAGS@
diff --git a/src/lib/tsuite_evas_hook.c b/src/lib/tsuite_evas_hook.c
index fdb4ac3..e2dcdf7 100644
--- a/src/lib/tsuite_evas_hook.c
+++ b/src/lib/tsuite_evas_hook.c
@@ -65,7 +65,7 @@ _tsuite_verbosef(const char *fmt, ...)
  * @ingroup Tsuite
  */
 
-static unsigned int
+unsigned int
 evt_time_get(unsigned int tm, Variant_st *v)
 {
    switch(tsuite_event_mapping_type_get(v->t.type))
diff --git a/src/lib/tsuite_file_data.c b/src/lib/tsuite_file_data.c
index 5afe7d7..ecbaa45 100644
--- a/src/lib/tsuite_file_data.c
+++ b/src/lib/tsuite_file_data.c
@@ -211,7 +211,7 @@ write_events(const char *filename, Lists_st *vr_list)
 }
 
 Lists_st *
-read_events(char *filename, Timer_Data *td)
+read_events(const char *filename, Timer_Data *td)
 {
    Lists_st *vr_list;
    Eet_File *fp = eet_open(filename, EET_FILE_MODE_READ);
diff --git a/src/lib/tsuite_file_data.h b/src/lib/tsuite_file_data.h
index 8f53856..f453f22 100644
--- a/src/lib/tsuite_file_data.h
+++ b/src/lib/tsuite_file_data.h
@@ -1,11 +1,40 @@
 #ifndef _TSUITE_EVAS_HOOK_H
 #define _TSUITE_EVAS_HOOK_H
 
+#include <Evas.h>
+#include <Eet.h>
+
 #define CACHE_FILE_ENTRY "cache"
 
 /* Macro declaring a function argument to be unused */
 #define __UNUSED__ __attribute__((unused))
 
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef EXACTNESS_BUILD
+#  ifdef DLL_EXPORT
+#   define EAPI __declspec(dllexport)
+#  else
+#   define EAPI
+#  endif /* ! DLL_EXPORT */
+# else
+#  define EAPI __declspec(dllimport)
+# endif /* ! EXACTNESS_BUILD */
+#else
+# ifdef __GNUC__
+#  if __GNUC__ >= 4
+#   define EAPI __attribute__ ((visibility("default")))
+#  else
+#   define EAPI
+#  endif
+# else
+#  define EAPI
+# endif
+#endif /* ! _WIN32 */
+
 enum _Tsuite_Event_Type
 {  /*  Add any supported events here */
    TSUITE_EVENT_NOT_SUPPORTED = 0,
@@ -220,7 +249,9 @@ const char * 
tsuite_event_mapping_type_str_get(Tsuite_Event_Type t);
 const char * _variant_type_get(const void *data, Eina_Bool *unknow);
 Eina_Bool _variant_type_set(const char *type, void *data, Eina_Bool unknow);
 
-Lists_st * free_events(Lists_st *st, char *recording);
-void write_events(const char *filename, Lists_st *vr_list);
-Lists_st *read_events(char *filename, Timer_Data *td);
+EAPI Tsuite_Event_Type tsuite_event_mapping_type_get(const char *name);
+EAPI Lists_st * free_events(Lists_st *st, char *recording);
+EAPI void write_events(const char *filename, Lists_st *vr_list);
+EAPI Lists_st *read_events(const char *filename, Timer_Data *td);
+EAPI unsigned int evt_time_get(unsigned int tm, Variant_st *v);
 #endif

-- 


Reply via email to