edje: add edje_watch.
authorcedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 8 May 2012 10:35:57 +0000 (10:35 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 8 May 2012 10:35:57 +0000 (10:35 +0000)
edje_watch call edje_cc and monitor all the source file (edc, font
image, sound). If any of them change, it call edje_cc, update its
watching list and so on. edje_watch as the same command line as
edje_cc.
   Still a little bit rought, but it's the beginning of an interesting
experiment.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/edje@70872 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

ChangeLog
NEWS
configure.ac
src/bin/Makefile.am
src/bin/edje_cc.c
src/bin/edje_cc.h
src/bin/edje_cc_out.c
src/bin/edje_cc_parse.c
src/bin/edje_watch.c [new file with mode: 0644]
src/bin/epp/cpplib.c
src/bin/epp/cpplib.h

index 2d9cb5f..ed36acc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 2012-05-02  Cedric Bail
 
        * Doing less allocation and reuse Evas_Map does help.
+
+2012-05-08  Cedric Bail
+
+       * Add edje_watch tools to automatically rebuild edc.
diff --git a/NEWS b/NEWS
index 88c69a6..87c57ba 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,9 @@ Edje 1.3.0
 Changes since Edje 1.2.0:
 -------------------------
 
+Additions:
+    * Add edje_watch to monitore change on edje source.
+
 Improvements:
     * Allocate once and reuse Evas_Map.
 
index 5198f36..c173bb0 100644 (file)
@@ -104,6 +104,7 @@ EFL_ENABLE_BIN([edje-recc])
 EFL_ENABLE_BIN([edje-player])
 EFL_ENABLE_BIN([edje-inspector])
 EFL_ENABLE_BIN([edje-external-inspector])
+EFL_ENABLE_BIN([edje-watch])
 
 # Optional EDJE_PROGRAM_CACHE (use much more ram, but increase speed in some cases)
 want_edje_program_cache="no"
@@ -292,6 +293,18 @@ PKG_CHECK_MODULES([ECORE_IMF],
    ],
    [have_ecore_imf="no"])
 
+have_eio="no"
+PKG_CHECK_MODULES([EIO],
+   [
+    eio >= 1.0.0
+   ],
+   [
+    AC_DEFINE([HAVE_EIO], [1], [Eio is available for monitoring file assynchronously])
+    have_eio="yes"
+    requirement_edje="eio >= 1.0.0 ${requirement_edje}"
+   ],
+   [have_eio="no"])
+
 # Enable Multisense use
 want_multisense="yes"
 AC_ARG_ENABLE([multisense],
@@ -467,6 +480,9 @@ if test "x$have_edje_external_inspector" = "xyes"; then
    PKG_CHECK_MODULES([EDJE_EXTERNAL_INSPECTOR], [ecore >= 1.2.0 evas >= 1.2.0 eina >= 1.2.0])
 fi
 
+if test "x$have_edje_watch" = "xyes"; then
+   PKG_CHECK_MODULES([EDJE_WATCH], [ecore >= 1.2.0 eina >= 1.2.0 eio >= 1.0.0])
+fi
 
 ### Checks for header files
 AC_CHECK_HEADERS([locale.h sys/resource.h])
@@ -614,6 +630,7 @@ echo "  Build edje_recc..............: $have_edje_recc"
 echo "  Build edje_player............: $have_edje_player"
 echo "  Build edje_inspector.........: $have_edje_inspector"
 echo "  Build edje_external_inspector: $have_edje_external_inspector"
+echo "  Build edje_watch.............: $have_edje_watch"
 echo
 echo "Compilation............: make (or gmake)"
 echo "  CPPFLAGS.............: $CPPFLAGS"
index a936d5a..85458b3 100644 (file)
@@ -6,9 +6,9 @@ endif
 
 bin_SCRIPTS = @EDJE_RECC_PRG@
 
-bin_PROGRAMS = @EDJE_CC_PRG@ @EDJE_DECC_PRG@ @EDJE_PLAYER_PRG@ @EDJE_INSPECTOR_PRG@ @EDJE_EXTERNAL_INSPECTOR_PRG@
+bin_PROGRAMS = @EDJE_CC_PRG@ @EDJE_DECC_PRG@ @EDJE_PLAYER_PRG@ @EDJE_INSPECTOR_PRG@ @EDJE_EXTERNAL_INSPECTOR_PRG@ @EDJE_WATCH_PRG@
 
-EXTRA_PROGRAMS = edje_cc edje_decc edje_player edje_inspector edje_external_inspector
+EXTRA_PROGRAMS = edje_cc edje_decc edje_player edje_inspector edje_external_inspector edje_watch
 
 edje_cc_SOURCES = \
 edje_cc.c \
@@ -26,10 +26,20 @@ edje_cc_CPPFLAGS = \
 -DPACKAGE_LIB_DIR=\"$(libdir)\" \
 -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
 -DEPP_DIR=\"$(libdir)/$(PACKAGE)/utils\" \
-@EDJE_CFLAGS@ @EDJE_CC_CFLAGS@ @EVIL_CFLAGS@ @SNDFILE_CFLAGS@
+@EDJE_CFLAGS@ @EDJE_CC_CFLAGS@ @EIO_CFLAGS@ @EVIL_CFLAGS@ @SNDFILE_CFLAGS@
 edje_cc_LDADD = $(top_builddir)/src/lib/libedje.la @EDJE_CC_LIBS@ @EVIL_LIBS@ @VORBISENC_LIBS@ @FLAC_LIBS@ @SNDFILE_LIBS@ -lm
 edje_cc_LDFLAGS = @lt_enable_auto_import@
 
+edje_watch_SOURCES = \
+edje_watch.c
+
+edje_watch_CPPFLAGS = \
+-I$(top_srcdir)/src/bin \
+-I$(top_srcdir)/src/lib \
+-DPACKAGE_BIN_DIR=\"$(bindir)\" \
+@EDJE_CFLAGS@ @EDJE_CC_CFLAGS@ @EIO_CFLAGS@ @EVIL_CFLAGS@ @EDJE_WATCH_CFLAGS@
+edje_watch_LDADD = $(top_builddir)/src/lib/libedje.la @EDJE_WATCH_LIBS@
+edje_watch_LDFLAGS = @lt_enable_auto_import@
 
 edje_decc_SOURCES = \
 edje_decc.c \
@@ -40,7 +50,7 @@ edje_cc_sources.c
 edje_decc_CPPFLAGS = \
 -I$(top_srcdir)/src/bin \
 -I$(top_srcdir)/src/lib \
-@EDJE_CFLAGS@ @EDJE_DECC_CFLAGS@ @EVIL_CFLAGS@
+@EDJE_CFLAGS@ @EDJE_DECC_CFLAGS@ @EIO_CFLAGS@ @EVIL_CFLAGS@
 edje_decc_LDADD = $(top_builddir)/src/lib/libedje.la @EDJE_DECC_LIBS@ @VORBISENC_LIBS@ @FLAC_LIBS@ @SNDFILE_LIBS@
 edje_decc_LDFLAGS = @lt_enable_auto_import@
 
@@ -48,7 +58,7 @@ edje_player_SOURCES = edje_player.c
 edje_player_CPPFLAGS = \
 -I$(top_srcdir)/src/bin \
 -I$(top_srcdir)/src/lib \
-@EDJE_PLAYER_CFLAGS@ @EVIL_CFLAGS@
+@EDJE_PLAYER_CFLAGS@ @EVIL_CFLAGS@ @EIO_CFLAGS@
 edje_player_LDADD = $(top_builddir)/src/lib/libedje.la @EDJE_PLAYER_LIBS@ @EVIL_LIBS@ @VORBISENC_LIBS@ @FLAC_LIBS@ @SNDFILE_LIBS@
 edje_player_LDFLAGS = @lt_enable_auto_import@
 
@@ -56,7 +66,7 @@ edje_inspector_SOURCES = edje_inspector.c
 edje_inspector_CPPFLAGS = \
 -I$(top_srcdir)/src/bin \
 -I$(top_srcdir)/src/lib \
-@EDJE_INSPECTOR_CFLAGS@
+@EDJE_INSPECTOR_CFLAGS@ @EIO_CFLAGS@
 edje_inspector_LDADD = $(top_builddir)/src/lib/libedje.la @EDJE_INSPECTOR_LIBS@ @VORBISENC_LIBS@ @FLAC_LIBS@
 edje_inspector_LDFLAGS = @lt_enable_auto_import@
 
@@ -64,7 +74,7 @@ edje_external_inspector_SOURCES = edje_external_inspector.c
 edje_external_inspector_CPPFLAGS = \
 -I$(top_srcdir)/src/bin \
 -I$(top_srcdir)/src/lib \
-@EDJE_EXTERNAL_INSPECTOR_CFLAGS@
+@EDJE_EXTERNAL_INSPECTOR_CFLAGS@ @EIO_CFLAGS@
 edje_external_inspector_LDADD = $(top_builddir)/src/lib/libedje.la @EDJE_EXTERNAL_INSPECTOR_LIBS@ @VORBISENC_LIBS@ @FLAC_LIBS@ @SNDFILE_LIBS@
 edje_external_inspector_LDFLAGS = @lt_enable_auto_import@
 
index b564fe5..ff2708c 100644 (file)
@@ -20,6 +20,7 @@ char      *file_in = NULL;
 char      *tmp_dir = NULL;
 char      *file_out = NULL;
 char      *progname = NULL;
+char      *watchfile = NULL;
 int        verbose = 0;
 
 int        no_lossy = 0;
@@ -38,6 +39,7 @@ main_help(void)
       "\n"
       "Where OPTIONS is one or more of:\n"
       "\n"
+      "-w files.txt             Dump all sources files path into files.txt\n"
       "-id image/directory      Add a directory to look in for relative path images\n"
       "-fd font/directory       Add a directory to look in for relative path fonts\n"
       "-sd sound/directory      Add a directory to look in for relative path sounds samples\n"
@@ -151,6 +153,12 @@ main(int argc, char **argv)
             i++;
             file_out = argv[i];
          }
+       else if ((!strcmp(argv[i], "-w")) && (i < (argc - 1)))
+         {
+             i++;
+             watchfile = argv[i];
+             unlink(watchfile);
+         }
        else if (!file_in)
          file_in = argv[i];
        else if (!file_out)
index 0291f29..56b5449 100644 (file)
@@ -194,6 +194,8 @@ void   *mem_alloc(size_t size);
 char   *mem_strdup(const char *s);
 #define SZ sizeof
 
+void    using_file(const char *filename);
+
 void    error_and_abort(Eet_File *ef, const char *fmt, ...);
 
 /* global vars */
@@ -205,6 +207,7 @@ extern char                  *file_in;
 extern char                  *tmp_dir;
 extern char                  *file_out;
 extern char                  *progname;
+extern char                  *watchfile;
 extern int                    verbose;
 extern int                    no_lossy;
 extern int                    no_comp;
index d195d78..f3b4358 100644 (file)
@@ -323,6 +323,7 @@ data_write_fonts(Eet_File *ef, int *font_num, int *input_bytes, int *input_raw_b
          {
             long pos;
 
+            using_file(fn->file);
             fseek(f, 0, SEEK_END);
             pos = ftell(f);
             rewind(f);
@@ -350,6 +351,7 @@ data_write_fonts(Eet_File *ef, int *font_num, int *input_bytes, int *input_raw_b
                    {
                       long pos;
 
+                      using_file(buf);
                       fseek(f, 0, SEEK_END);
                       pos = ftell(f);
                       rewind(f);
@@ -533,7 +535,10 @@ data_write_images(Eet_File *ef, int *image_num, int *input_bytes, int *input_raw
                            evas_object_image_file_set(im, buf, NULL);
                            load_err = evas_object_image_load_error_get(im);
                            if (load_err == EVAS_LOAD_ERROR_NONE)
-                             break;
+                             {
+                                 using_file(buf);
+                                 break;
+                             }
                            evas_object_del(im);
                            im = NULL;
                            if (load_err != EVAS_LOAD_ERROR_DOES_NOT_EXIST)
@@ -552,6 +557,7 @@ data_write_images(Eet_File *ef, int *image_num, int *input_bytes, int *input_raw
                                 evas_object_del(im);
                                 im = NULL;
                              }
+                            if (im) using_file(img->entry);
                         }
                    }
                  if (im)
@@ -716,8 +722,10 @@ data_write_sounds(Eet_File * ef, int *sound_num, int *input_bytes, int *input_ra
              stat(enc_info->file, &st);
              size = st.st_size;
              fp = fopen(enc_info->file, "rb");
+            if (fp) using_file(enc_info->file);
 #else
              fp = fopen(snd_path, "rb");
+            if (fp) using_file(snd_path);
 #endif
              if (!fp)
                {
@@ -2167,3 +2175,15 @@ data_process_script_lookups(void)
        strncpy(cl->ptr, buf, n);
      }
 }
+
+void
+using_file(const char *filename)
+{
+  FILE *f;
+
+  f = fopen(watchfile, "a");
+  if (!f) return ;
+  fputs(filename, f);
+  fputc('\n', f);
+  fclose(f);
+}
index adc08d3..8161977 100644 (file)
@@ -739,8 +739,8 @@ compile(void)
                  eina_prefix_lib_get(pfx));
         if (ecore_file_exists(buf2))
           {
-             snprintf(buf, sizeof(buf), "%s %s -I%s %s -o %s",
-                      buf2, file_in, inc, def, tmpn);
+             snprintf(buf, sizeof(buf), "%s -a %s %s -I%s %s -o %s",
+                      buf2, watchfile ? watchfile : "/dev/null", file_in, inc, def, tmpn);
              ret = system(buf);
           }
         else
diff --git a/src/bin/edje_watch.c b/src/bin/edje_watch.c
new file mode 100644 (file)
index 0000000..f850291
--- /dev/null
@@ -0,0 +1,127 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <Eina.h>
+#include <Ecore.h>
+#include <Eio.h>
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+char watchfile[PATH_MAX];
+char *edje_cc_command = NULL;
+Eina_List *watching = NULL;
+Ecore_Timer *timeout = NULL;
+
+static void
+read_watch_file(const char *file)
+{
+   Eina_File *f;
+   Eina_Iterator *it;
+   Eina_File_Lines *ln;
+   Eio_Monitor *mon;
+   Eina_List *r = NULL;
+
+   f = eina_file_open(file, EINA_FALSE);
+   if (!f) return ;
+
+   it = eina_file_map_lines(f);
+   if (!it) goto err;
+
+   EINA_ITERATOR_FOREACH(it, ln)
+     {
+        const char *path;
+
+        path = eina_stringshare_add_length(ln->line.start, ln->length);
+        r = eina_list_append(r, eio_monitor_add(path));
+        eina_stringshare_del(path);
+     }
+   eina_iterator_free(it);
+
+   EINA_LIST_FREE(watching, mon)
+     eio_monitor_del(mon);
+   watching = r;
+
+ err:
+   eina_file_close(f);
+}
+
+Eina_Bool
+rebuild(void *data __UNUSED__)
+{
+   fprintf(stderr, "SYSTEM('%s')\n", edje_cc_command);
+   if (system(edje_cc_command) == 0)
+     read_watch_file(watchfile);
+   fprintf(stderr, "DONE\n");
+
+   timeout = NULL;
+   return EINA_FALSE;
+}
+
+Eina_Bool
+some_change(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
+{
+   Eio_Monitor_Event *ev = event;
+
+   fprintf(stderr, "EVENT %i on [%s]\n", type, ev->filename);
+   if (timeout) ecore_timer_del(timeout);
+   timeout = ecore_timer_add(0.5, rebuild, NULL);
+
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+int
+main(int argc, char **argv)
+{
+   char *watchout;
+   Eina_Strbuf *buf;
+   int tfd;
+   int i;
+
+   eina_init();
+   ecore_init();
+   eio_init();
+
+   if (argc < 2) return -1;
+
+   ecore_event_handler_add(EIO_MONITOR_FILE_MODIFIED, some_change, NULL);
+   ecore_event_handler_add(EIO_MONITOR_FILE_CREATED, some_change, NULL);
+   ecore_event_handler_add(EIO_MONITOR_FILE_DELETED, some_change, NULL);
+   ecore_event_handler_add(EIO_MONITOR_FILE_CLOSED, some_change, NULL);
+
+#ifdef HAVE_EVIL
+   watchout = (char *)evil_tmpdir_get();
+#else
+   watchout = "/tmp";
+#endif
+
+   snprintf(watchfile, PATH_MAX, "%s/edje_watch-tmp-XXXXXX", watchout);
+
+   tfd = mkstemp(watchfile);
+   if (tfd < 0) return -1;
+   close(tfd);
+
+   buf = eina_strbuf_new();
+   if (!buf) return -1;
+
+   eina_strbuf_append_printf(buf, "%s/edje_cc -w %s ", PACKAGE_BIN_DIR, watchfile);
+   for (i = 1; i < argc; ++i)
+     eina_strbuf_append_printf(buf, "%s ", argv[i]);
+
+   edje_cc_command = eina_strbuf_string_steal(buf);
+
+   eina_strbuf_free(buf);
+
+   fprintf(stderr, "SYSTEM('%s')\n", edje_cc_command);
+   system(edje_cc_command);
+   read_watch_file(watchfile);
+
+   ecore_main_loop_begin();
+
+   eio_shutdown();
+   ecore_shutdown();
+   eina_shutdown();
+
+   return 1;
+}
index 132d2a9..30c7f01 100644 (file)
@@ -5489,6 +5489,7 @@ open_include_file(cpp_reader * pfile, char *filename,
        && !strncmp(searchptr->fname, filename, p - filename))
      {
        /* FILENAME is in SEARCHPTR, which we've already checked.  */
+        using_file(filename);
        return open(filename, O_RDONLY | O_BINARY, 0666);
      }
    if (p == filename)
@@ -5508,8 +5509,12 @@ open_include_file(cpp_reader * pfile, char *filename,
      }
    for (map = read_name_map(pfile, dir); map; map = map->map_next)
       if (!strcmp(map->map_from, from))
-        return open(map->map_to, O_RDONLY | O_BINARY, 0666);
+        {
+           using_file(map->map_to);
+           return open(map->map_to, O_RDONLY | O_BINARY, 0666);
+        }
 
+   using_file(filename);
    return open(filename, O_RDONLY | O_BINARY, 0666);
 }
 
@@ -5519,6 +5524,7 @@ static int
 open_include_file(cpp_reader * pfile __UNUSED__, char *filename,
                  file_name_list * searchptr __UNUSED__)
 {
+   using_file(filename);
    return open(filename, O_RDONLY | O_BINARY, 0666);
 }
 
@@ -6561,6 +6567,20 @@ cpp_handle_options(cpp_reader * pfile, int argc, char **argv)
                     i++, push_pending(pfile, "-D", argv[i]);
                  break;
 
+              case 'a':
+                  {
+                     if (!strcmp(argv[i], "-a"))
+                       {
+                          if (i + 1 == argc)
+                            cpp_fatal("Filename missing after `-a` option");
+                          else if (strcmp(argv[++i], "/dev/null"))
+                            {
+                               opts->watchfile = argv[i];
+                            }
+                       }
+                    break;
+                  }
+
               case 'A':
                  {
                     char               *p = NULL;
@@ -7425,3 +7445,17 @@ cpp_perror_with_name(cpp_reader * pfile, const char *name)
  *
  * Support for_lint flag.
  */
+
+extern cpp_options         options;
+
+void
+using_file(const char *filename)
+{
+   FILE *f;
+
+   f = fopen(options.watchfile, "a");
+   if (!f) return ;
+   fputs(filename, f);
+   fputc('\n', f);
+   fclose(f);
+}
index 5653dd2..a34a765 100644 (file)
@@ -473,6 +473,9 @@ struct cpp_options {
 
    /* Target-name to write with the dependency information.  */
    char               *deps_target;
+
+   /* Target file to write all include file */
+   const char         *watchfile;
 };
 
 #define CPP_TRADITIONAL(PFILE) (CPP_OPTIONS(PFILE)-> traditional)
@@ -636,6 +639,8 @@ void               *xmalloc(unsigned size);
 void               *xrealloc(void *old, unsigned size);
 void               *xcalloc(unsigned number, unsigned size);
 
+void                using_file(const char *filename);
+
 #ifdef __EMX__
 #define PATH_SEPARATOR ';'
 #endif