<commit_before>/*
 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
 */
#include "e.h"

/* local subsystem functions */
static void _e_order_free       (E_Order *eo);
static void _e_order_cb_monitor (void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const char *path);
static void _e_order_read       (E_Order *eo);
static void _e_order_save       (E_Order *eo);

static int  _e_order_cb_efreet_desktop_change(void *data, int ev_type, void *ev);

static Evas_List *orders = NULL;
static Evas_List *handlers = NULL;

/* externally accessible functions */
EAPI int
e_order_init(void)
{
   handlers = evas_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_DESKTOP_CHANGE, _e_order_cb_efreet_desktop_change, NULL));

   return 1;
}

EAPI int
e_order_shutdown(void)
{
   orders = evas_list_free(orders);

   while (handlers)
     {
	ecore_event_handler_del(handlers->data);
	handlers = evas_list_remove_list(handlers, handlers);
     }
   return 1;
}

EAPI E_Order *
e_order_new(const char *path)
{
   E_Order *eo;
 
   eo = E_OBJECT_ALLOC(E_Order, E_ORDER_TYPE, _e_order_free);
   if (!eo) return NULL;

   if (path) eo->path = evas_stringshare_add(path);
   _e_order_read(eo);
   eo->monitor = ecore_file_monitor_add(path, _e_order_cb_monitor, eo);

   orders = evas_list_append(orders, eo);

   return eo;
}

EAPI void
e_order_update_callback_set(E_Order *eo, void (*cb)(void *data, E_Order *eo), void *data)
{
   E_OBJECT_CHECK(eo);
   E_OBJECT_TYPE_CHECK(eo, E_ORDER_TYPE);

   eo->cb.update = cb;
   eo->cb.data = data;
}

EAPI void
e_order_remove(E_Order *eo, Efreet_Desktop *desktop)
{
   E_OBJECT_CHECK(eo);
   E_OBJECT_TYPE_CHECK(eo, E_ORDER_TYPE);

   eo->desktops = evas_list_remove(eo->desktops, desktop);
   _e_order_save(eo);
}

EAPI void
e_order_append(E_Order *eo, Efreet_Desktop *desktop)
{
   E_OBJECT_CHECK(eo);
   E_OBJECT_TYPE_CHECK(eo, E_ORDER_TYPE);

   eo->desktops = evas_list_append(eo->desktops, desktop);
   _e_order_save(eo);
}

EAPI void
e_order_prepend_relative(E_Order *eo, Efreet_Desktop *desktop, Efreet_Desktop *before)
{
   E_OBJECT_CHECK(eo);
   E_OBJECT_TYPE_CHECK(eo, E_ORDER_TYPE);

   eo->desktops = evas_list_prepend_relative(eo->desktops, desktop, before);
   _e_order_save(eo);
}

EAPI void
e_order_files_append(E_Order *eo, Evas_List *files)
{
   Evas_List *l;

   E_OBJECT_CHECK(eo);
   E_OBJECT_TYPE_CHECK(eo, E_ORDER_TYPE);

   for (l = files; l ; l = l->next)
     {
	Efreet_Desktop *desktop;
	const char *file;

	file = l->data;
	desktop = efreet_desktop_get(file);
	if (!desktop) continue;
	eo->desktops = evas_list_append(eo->desktops, desktop);
     }
   _e_order_save(eo);
}

EAPI void
e_order_files_prepend_relative(E_Order *eo, Evas_List *files, Efreet_Desktop *before)
{
   Evas_List *l;

   E_OBJECT_CHECK(eo);
   E_OBJECT_TYPE_CHECK(eo, E_ORDER_TYPE);

   for (l = files; l ; l = l->next)
     {
	Efreet_Desktop *desktop;
	const char *file;

	file = l->data;
	desktop = efreet_desktop_get(file);
	if (!desktop) continue;
	eo->desktops = evas_list_prepend_relative(eo->desktops, desktop, before);
     }
   _e_order_save(eo);
}

EAPI void
e_order_clear(E_Order *eo)
{
   E_OBJECT_CHECK(eo);
   E_OBJECT_TYPE_CHECK(eo, E_ORDER_TYPE);

   while (eo->desktops)
     eo->desktops = evas_list_remove_list(eo->desktops, eo->desktops);
   _e_order_save(eo);
}

/* local subsystem functions */
static void
_e_order_free(E_Order *eo)
{
   evas_list_free(eo->desktops);
   if (eo->path) evas_stringshare_del(eo->path);
   if (eo->monitor) ecore_file_monitor_del(eo->monitor);
   orders = evas_list_remove(orders, eo);
   free(eo);
}

static void
_e_order_cb_monitor(void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const char *path)
{
   E_Order *eo;

   eo = data;

   /* It doesn't really matter what the change is, just re-read the file */
   _e_order_read(eo);
   if (eo->cb.update) eo->cb.update(eo->cb.data, eo);
}

static void
_e_order_read(E_Order *eo)
{
   FILE *f;
   char *dir;

   eo->desktops = evas_list_free(eo->desktops);
   if (!eo->path) return;

   dir = ecore_file_get_dir(eo->path);
   f = fopen(eo->path, "rb");
   if (f)
     {
	char buf[4096], buf2[PATH_MAX];

	while (fgets(buf, sizeof(buf), f))
	  {
	     int len;

	     len = strlen(buf);
	     if (len > 0)
	       {
		  if (buf[len - 1] == '\n')
		    {
		       buf[len - 1] = 0;
		       len--;
		    }
		  if (len > 0)
		    {
		       Efreet_Desktop *desktop;
		       
		       desktop = NULL;
		       if ((dir) && (buf[0] != '/'))
			 {
			    snprintf(buf2, sizeof(buf2), "%s/%s", dir, buf);
			    desktop = efreet_desktop_get(buf2);
			 }
		       if (!desktop)
			 {
			    snprintf(buf2, sizeof(buf2), 
				     "%s",
//				     "%s/.e/e/applications/all/%s",
				     e_user_homedir_get(), buf);
			    desktop = efreet_desktop_get(buf2);
			 }
		       if (!desktop)
			 desktop = efreet_util_desktop_file_id_find(buf);
		       if (desktop) eo->desktops = evas_list_append(eo->desktops, desktop);
		    }
	       }
	  }
	fclose(f);
     }
   if (dir) free(dir);
}

static void
_e_order_save(E_Order *eo)
{
   FILE *f;
   Evas_List *l;

   if (!eo->path) return;
   f = fopen(eo->path, "wb");
   if (!f) return;
<commit_msg>Patch from morlenxus to fix .order files that reference a full path.<commit_after>/*
 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
 */
#include "e.h"

/* local subsystem functions */
static void _e_order_free       (E_Order *eo);
static void _e_order_cb_monitor (void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const char *path);
static void _e_order_read       (E_Order *eo);
static void _e_order_save       (E_Order *eo);

static int  _e_order_cb_efreet_desktop_change(void *data, int ev_type, void *ev);

static Evas_List *orders = NULL;
static Evas_List *handlers = NULL;

/* externally accessible functions */
EAPI int
e_order_init(void)
{
   handlers = evas_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_DESKTOP_CHANGE, _e_order_cb_efreet_desktop_change, NULL));

   return 1;
}

EAPI int
e_order_shutdown(void)
{
   orders = evas_list_free(orders);

   while (handlers)
     {
	ecore_event_handler_del(handlers->data);
	handlers = evas_list_remove_list(handlers, handlers);
     }
   return 1;
}

EAPI E_Order *
e_order_new(const char *path)
{
   E_Order *eo;
 
   eo = E_OBJECT_ALLOC(E_Order, E_ORDER_TYPE, _e_order_free);
   if (!eo) return NULL;

   if (path) eo->path = evas_stringshare_add(path);
   _e_order_read(eo);
   eo->monitor = ecore_file_monitor_add(path, _e_order_cb_monitor, eo);

   orders = evas_list_append(orders, eo);

   return eo;
}

EAPI void
e_order_update_callback_set(E_Order *eo, void (*cb)(void *data, E_Order *eo), void *data)
{
   E_OBJECT_CHECK(eo);
   E_OBJECT_TYPE_CHECK(eo, E_ORDER_TYPE);

   eo->cb.update = cb;
   eo->cb.data = data;
}

EAPI void
e_order_remove(E_Order *eo, Efreet_Desktop *desktop)
{
   E_OBJECT_CHECK(eo);
   E_OBJECT_TYPE_CHECK(eo, E_ORDER_TYPE);

   eo->desktops = evas_list_remove(eo->desktops, desktop);
   _e_order_save(eo);
}

EAPI void
e_order_append(E_Order *eo, Efreet_Desktop *desktop)
{
   E_OBJECT_CHECK(eo);
   E_OBJECT_TYPE_CHECK(eo, E_ORDER_TYPE);

   eo->desktops = evas_list_append(eo->desktops, desktop);
   _e_order_save(eo);
}

EAPI void
e_order_prepend_relative(E_Order *eo, Efreet_Desktop *desktop, Efreet_Desktop *before)
{
   E_OBJECT_CHECK(eo);
   E_OBJECT_TYPE_CHECK(eo, E_ORDER_TYPE);

   eo->desktops = evas_list_prepend_relative(eo->desktops, desktop, before);
   _e_order_save(eo);
}

EAPI void
e_order_files_append(E_Order *eo, Evas_List *files)
{
   Evas_List *l;

   E_OBJECT_CHECK(eo);
   E_OBJECT_TYPE_CHECK(eo, E_ORDER_TYPE);

   for (l = files; l ; l = l->next)
     {
	Efreet_Desktop *desktop;
	const char *file;

	file = l->data;
	desktop = efreet_desktop_get(file);
	if (!desktop) continue;
	eo->desktops = evas_list_append(eo->desktops, desktop);
     }
   _e_order_save(eo);
}

EAPI void
e_order_files_prepend_relative(E_Order *eo, Evas_List *files, Efreet_Desktop *before)
{
   Evas_List *l;

   E_OBJECT_CHECK(eo);
   E_OBJECT_TYPE_CHECK(eo, E_ORDER_TYPE);

   for (l = files; l ; l = l->next)
     {
	Efreet_Desktop *desktop;
	const char *file;

	file = l->data;
	desktop = efreet_desktop_get(file);
	if (!desktop) continue;
	eo->desktops = evas_list_prepend_relative(eo->desktops, desktop, before);
     }
   _e_order_save(eo);
}

EAPI void
e_order_clear(E_Order *eo)
{
   E_OBJECT_CHECK(eo);
   E_OBJECT_TYPE_CHECK(eo, E_ORDER_TYPE);

   while (eo->desktops)
     eo->desktops = evas_list_remove_list(eo->desktops, eo->desktops);
   _e_order_save(eo);
}

/* local subsystem functions */
static void
_e_order_free(E_Order *eo)
{
   evas_list_free(eo->desktops);
   if (eo->path) evas_stringshare_del(eo->path);
   if (eo->monitor) ecore_file_monitor_del(eo->monitor);
   orders = evas_list_remove(orders, eo);
   free(eo);
}

static void
_e_order_cb_monitor(void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const char *path)
{
   E_Order *eo;

   eo = data;

   /* It doesn't really matter what the change is, just re-read the file */
   _e_order_read(eo);
   if (eo->cb.update) eo->cb.update(eo->cb.data, eo);
}

static void
_e_order_read(E_Order *eo)
{
   FILE *f;
   char *dir;

   eo->desktops = evas_list_free(eo->desktops);
   if (!eo->path) return;

   dir = ecore_file_get_dir(eo->path);
   f = fopen(eo->path, "rb");
   if (f)
     {
	char buf[4096], buf2[PATH_MAX];

	while (fgets(buf, sizeof(buf), f))
	  {
	     int len;

	     len = strlen(buf);
	     if (len > 0)
	       {
		  if (buf[len - 1] == '\n')
		    {
		       buf[len - 1] = 0;
		       len--;
		    }
		  if (len > 0)
		    {
		       Efreet_Desktop *desktop;
		       
		       desktop = NULL;
		       if (buf[0] == '/')
		         desktop = efreet_desktop_get(buf);
		       if (!desktop)
		         desktop = efreet_desktop_get(ecore_file_get_file(buf));
		       if (!desktop)
			 desktop = efreet_util_desktop_file_id_find(ecore_file_get_file(buf));
		       if (desktop) eo->desktops = evas_list_append(eo->desktops, desktop);
		    }
	       }
	  }
	fclose(f);
     }
   if (dir) free(dir);
}

static void
_e_order_save(E_Order *eo)
{
   FILE *f;
   Evas_List *l;

   if (!eo->path) return;
   f = fopen(eo->path, "wb");
   if (!f) return;

{'fraction_non_alphanumeric': 0.1325090059390517, 'fraction_numerical': 0.004673352156557297, 'mean_word_length': 3.6775956284153004, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 89, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3052048', 'n_tokens_mistral': 4538, 'n_tokens_neox': 4278, 'n_words': 791}