soylent r273 - trunk/libsoylent



Author: svenp
Date: Mon Aug 11 21:51:20 2008
New Revision: 273
URL: http://svn.gnome.org/viewvc/soylent?rev=273&view=rev

Log:
added a bunch of utility functions for diffing lists and splitting / joining strings

Modified:
   trunk/libsoylent/sl-priv-util.c
   trunk/libsoylent/sl-priv-util.h

Modified: trunk/libsoylent/sl-priv-util.c
==============================================================================
--- trunk/libsoylent/sl-priv-util.c	(original)
+++ trunk/libsoylent/sl-priv-util.c	Mon Aug 11 21:51:20 2008
@@ -24,12 +24,14 @@
 #include "sl-priv-util.h"
 #include "sl-attribute-eds.h"
 
+#include <string.h>
+
 static GEqualFunc compare_equal;
 
 ESource *
 sl_priv_util_get_source (ESourceList *source_tree, const gchar *name)
 {
-  g_return_val_if_fail (name != NULL, FALSE);
+  g_return_val_if_fail (source_tree != NULL && name != NULL, NULL);
   
   GSList *groups = e_source_list_peek_groups (source_tree);
   for (; groups != NULL; groups = groups->next)
@@ -53,6 +55,8 @@
 ESourceGroup *
 sl_priv_util_source_tree_get_default_group (ESourceList *source_tree)
 {
+  g_return_val_if_fail (source_tree != NULL, NULL);
+  
   GSList *groups = e_source_list_peek_groups (source_tree);
   g_assert (groups != NULL);
   return groups->data;
@@ -60,6 +64,8 @@
 
 gboolean sl_priv_util_lists_equal (GList *a, GList *b, GEqualFunc equal)
 {
+  g_return_val_if_fail (equal != NULL, FALSE);
+  
   while (a != NULL && b != NULL)
     {
       if (!equal (a->data, b->data))
@@ -82,6 +88,8 @@
 gboolean
 sl_priv_util_list_contains (GList *list, gpointer data, GEqualFunc equal)
 {
+  g_return_val_if_fail (data != NULL && equal != NULL, FALSE);
+  
   compare_equal = equal;
   return (g_list_find_custom (list, data, sl_priv_util_compare_by_equal) != NULL);
 }
@@ -89,6 +97,8 @@
 void
 sl_priv_util_list_print (GList *list, const gchar *title)
 {
+  g_return_if_fail (title != NULL);
+  
   g_print ("%s (%d):\n", title, g_list_length (list));
   for (; list != NULL; list = list->next)
     {
@@ -99,10 +109,14 @@
 void
 sl_priv_util_eattribute_list_print (GList *eattributes, const gchar *title)
 {
+  g_return_if_fail (title != NULL);
+  
   g_print ("%s (%d):\n", title, g_list_length (eattributes));
   for (; eattributes != NULL; eattributes = eattributes->next)
     {
       EVCardAttribute *eattr = eattributes->data;
+      g_return_if_fail (eattr != NULL);
+      
       g_print (" * %s\n", e_vcard_attribute_get_name (eattr));
     }
 }
@@ -110,6 +124,8 @@
 void
 sl_priv_util_attribute_list_print (GList *attributes, const gchar *title)
 {
+  g_return_if_fail (title != NULL);
+  
   g_print ("%s (%d):\n", title, g_list_length (attributes));
   for (; attributes != NULL; attributes = attributes->next)
     {
@@ -121,6 +137,8 @@
 void
 sl_priv_util_hash_table_print (GHashTable *table, const gchar *title)
 {
+  g_return_if_fail (table != NULL && title != NULL);
+  
   GHashTableIter iter;
   gpointer key = NULL;
   gpointer value = NULL;
@@ -135,7 +153,273 @@
 void
 sl_priv_util_hash_table_print_keys (GHashTable *table, const gchar *title)
 {
+  g_return_if_fail (table != NULL && title != NULL);
+  
   GList *keys = g_hash_table_get_keys (table);
   sl_priv_util_list_print (keys, title);
   g_list_free (keys);
 }
+
+gint
+sl_priv_util_compare_eattributes (EVCardAttribute *a, EVCardAttribute *b)
+{
+  g_return_val_if_fail (a != NULL && b != NULL, 0);
+  
+  const gchar *name_a = e_vcard_attribute_get_name (a);
+  const gchar *name_b = e_vcard_attribute_get_name (b);
+  return strcmp (name_a, name_b);
+}
+
+gboolean
+sl_priv_util_eattrlist_name_equal (GList *a, GList *b)
+{
+  g_return_val_if_fail (a != NULL && b != NULL, FALSE);
+  
+  const gchar *eattrname_a = e_vcard_attribute_get_name (a->data);
+  const gchar *eattrname_b = e_vcard_attribute_get_name (b->data);
+  return g_str_equal (eattrname_a, eattrname_b);
+}
+
+gboolean
+sl_priv_util_eattribute_equal (EVCardAttribute *a, EVCardAttribute *b)
+{
+  g_return_val_if_fail (a != NULL && b != NULL, FALSE);
+  
+  /* two eattributes are equal if their values are equal */
+  GList *evalues_a = e_vcard_attribute_get_values (a);
+  GList *evalues_b = e_vcard_attribute_get_values (b);
+  
+  return sl_priv_util_lists_equal (evalues_a, evalues_b, g_str_equal);
+}
+
+gboolean
+sl_priv_util_eattrlist_modified (GList *a, GList *b)
+{
+  g_return_val_if_fail (a != NULL && b != NULL, FALSE);
+  
+  /* TODO: ordering is taken into account here */
+  /* two lists of eattributes are modified if they are not equal */
+  
+  /* TODO: REMOVE AGAIN */
+  //return (!sl_priv_util_lists_equal (a, b, (GEqualFunc) sl_priv_util_eattribute_equal));
+  gboolean result = (!sl_priv_util_lists_equal (a, b, (GEqualFunc) sl_priv_util_eattribute_equal));
+  return result;
+}
+
+void
+sl_priv_util_list_set_diff (GList *a, GList *b, GEqualFunc equal, GList **added, GList **removed)
+{
+  sl_priv_util_list_set_diff_full (a, b, equal, NULL, added, removed, NULL, NULL);
+}
+
+void
+sl_priv_util_list_set_diff_full (GList *a, GList *b, GEqualFunc is_equal, GEqualFunc is_modified, GList **added, GList **removed, GList **modified, GList **rest)
+{
+  g_return_if_fail (is_equal != NULL);
+  
+  b = g_list_copy (b);
+  
+  sl_debug_util ("generating diff from two lists%s", "");
+  
+  if (added != NULL)
+    {
+      *added = NULL;
+    }
+  if (removed != NULL)
+    {
+      *removed = NULL;
+    }
+  if (modified != NULL)
+    {
+      *modified = NULL;
+    }
+  if (rest != NULL)
+    {
+      *rest = NULL;
+    }
+  GList *b_iter = NULL;
+  gboolean match = FALSE;
+  
+  for (; a != NULL; a = a->next)
+    {
+      match = FALSE;
+      b_iter = b;
+      
+      for (; b_iter != NULL; b_iter = b_iter->next)
+        {
+          if (is_equal (a->data, b_iter->data))
+            {
+              if (is_modified != NULL && is_modified (a->data, b_iter->data))
+                {
+                  if (modified != NULL)
+                    {
+                      *modified = g_list_append (*modified, a->data);
+                    }
+                }
+              else
+                {
+                  if (rest != NULL)
+                    {
+                      *rest = g_list_append (*rest, a->data);
+                    }
+                }
+              match = TRUE;
+              b = g_list_remove (b, b_iter->data);
+              break;
+            }
+        }
+      
+      if (!match)
+        {
+          if (added != NULL)
+            {
+              *added = g_list_append (*added, a->data);
+            }
+        }
+    }
+  
+  b_iter = b;
+  for (; b_iter != NULL; b_iter = b_iter->next)
+    {
+      if (removed != NULL)
+        {
+          *removed = g_list_append (*removed, b_iter->data);
+        }
+    }
+  
+  g_list_free (b);
+}
+
+/*
+ * (d, d, b, a, c, d, a) -> ((a, a), (b), (c), (d, d, d))
+ */
+GList *
+sl_priv_util_eattribute_flat_to_deep_list (GList *flat)
+{ 
+  sl_debug_util ("generating deep eattribute list from flat eattribute list%s", "");
+  
+  GList *deep = NULL;
+  flat = g_list_copy (flat);
+  flat = g_list_sort (flat, (GCompareFunc) sl_priv_util_compare_eattributes);
+  
+  for (; flat != NULL; flat = flat->next)
+    {
+      EVCardAttribute *eattr = flat->data;
+      g_assert (eattr != NULL);
+      const gchar *eattrname = e_vcard_attribute_get_name (eattr);
+      GList *eattrlist = g_list_append (NULL, eattr);
+      
+      while (TRUE)
+        {
+          GList *next = flat->next;
+          if (next == NULL || !g_str_equal (e_vcard_attribute_get_name (next->data), eattrname))
+            {
+              break;
+            }
+          flat = flat->next;
+          eattr = flat->data;
+          eattrlist = g_list_append (eattrlist, eattr);
+        }
+      
+      deep = g_list_append (deep, eattrlist);
+    }
+  
+  g_list_free (g_list_first (flat));
+  return deep;
+}
+
+void
+sl_priv_util_eattribute_deep_list_free (GList *deep)
+{
+  for (; deep != NULL; deep = deep->next)
+    {
+      g_list_free (deep->data);
+    }
+  g_list_free (deep);
+}
+
+
+/**
+ * sl_priv_util_strsplit_list:
+ * @string: a string to split
+ * @delimiter: a delimiter for splitting
+ * @max_tokens: the maximum number of tokens to split the string into. If it is
+ * less than 1, the string is split completly.
+ *
+ * Splits a string into a list of tokens. See g_strsplit() for more information
+ * on splitting strings.
+ *
+ * Returns: a list of strings (i.e. the tokens of the splitted string). The list
+ * should be freed with g_list_free().
+ */
+GList *sl_priv_util_strsplit_list (gchar *string, gchar *delimiter, gint max_tokens)
+{
+  /* g_strsplit checks all arguments */
+  gchar **tokens = g_strsplit (string, delimiter, max_tokens);
+  GList *list = sl_priv_util_strv_to_list (tokens);
+  g_free (tokens);
+  return list;
+}
+
+/**
+ * sl_priv_util_strjoin_list:
+ * @seperator: a seperator that should be inserted between the strings
+ * @strings: a list of strings that should be joined together
+ *
+ * Joins a list of strings together to one string. See g_strjoinv() for more
+ * information on joining strings.
+ *
+ * Returns: the joined string. The string should be freed with g_free().
+ */
+gchar *sl_priv_util_strjoin_list (gchar *seperator, GList *strings)
+{
+  /* g_strjoinv checks seperator, sl_priv_util_list_to_strv checks strings */
+  gchar **tokens = sl_priv_util_list_to_strv (strings);
+  gchar *string = g_strjoinv (seperator, tokens);
+  g_free (tokens);
+  return string;
+}
+
+/**
+ * sl_priv_util_strv_to_list:
+ * @strv: a NULL-terminated array of strings
+ *
+ * Creates a list of strings from a NULL-terminated array of strings. The items
+ * in the list will point to the same locations as the items in the array.
+ *
+ * Returns: a list of strings. The list should be freed with g_list_free().
+ */
+GList *sl_priv_util_strv_to_list (gchar **strv)
+{
+  g_return_val_if_fail (strv != NULL, NULL);
+  
+  GList *list = NULL;
+  for (; *strv != NULL; strv++)
+    {
+      list = g_list_prepend (list, *strv);
+    }
+  return g_list_reverse (list);
+}
+
+/**
+ * sl_priv_util_list_to_strv:
+ * @strings: a list of strings
+ *
+ * Creates a NULL-terminated array of strings from a list of strings. The items
+ * in the array will point to the same locations as the items in the list.
+ *
+ * Returns: a NULL-terminated array of strings. The array should be freed with
+ * g_free().
+ */
+gchar **sl_priv_util_list_to_strv (GList *strings)
+{
+  gchar **strv = g_new (gchar *, g_list_length (strings) + 1);
+  gchar **strvp = strv;
+  for (; strings != NULL; strings = strings->next)
+    {
+      *strvp = strings->data;
+      strvp++;
+    }
+  *strvp = NULL;
+  return strv;
+}

Modified: trunk/libsoylent/sl-priv-util.h
==============================================================================
--- trunk/libsoylent/sl-priv-util.h	(original)
+++ trunk/libsoylent/sl-priv-util.h	Mon Aug 11 21:51:20 2008
@@ -26,9 +26,39 @@
 
 #include <libebook/e-book.h>
 
-/* solve mutual inclusion */
-typedef struct _SlEntity    SlEntity;
-typedef struct _SlAttribute SlAttribute;
+/*#define SL_ENABLE_DEBUG_ALL*/
+
+#define sl_debug(unit, format, ...) g_printerr ("dbg[%s]: ", unit); \
+                                    g_printerr (format, __VA_ARGS__); \
+                                    g_printerr ("\n")
+
+#ifdef SL_ENABLE_DEBUG_ALL
+  #define SL_ENABLE_DEBUG_BOOK
+  #define SL_ENABLE_DEBUG_ENTITY
+  #define SL_ENABLE_DEBUG_ATTRIBUTE
+  #define SL_ENABLE_DEBUG_UTIL
+#endif
+
+#ifdef SL_ENABLE_DEBUG_BOOK
+  #define sl_debug_book(format, ...) sl_debug ("Book", format, __VA_ARGS__)
+#else
+  #define sl_debug_book(format, ...)
+#endif
+#ifdef SL_ENABLE_DEBUG_ENTITY
+  #define sl_debug_entity(format, ...) sl_debug ("Entity", format, __VA_ARGS__)
+#else
+  #define sl_debug_entity(format, ...)
+#endif
+#ifdef SL_ENABLE_DEBUG_ATTRIBUTE
+  #define sl_debug_attribute(format, ...) sl_debug ("Attribute", format, __VA_ARGS__)
+#else
+  #define sl_debug_attribute(format, ...)
+#endif
+#ifdef SL_ENABLE_DEBUG_UTIL
+  #define sl_debug_util(format, ...) sl_debug ("Util", format, __VA_ARGS__)
+#else
+  #define sl_debug_util(format, ...)
+#endif
 
 ESource *sl_priv_util_get_source (ESourceList *source_tree, const gchar *name);
 ESourceGroup *sl_priv_util_source_tree_get_default_group
@@ -42,4 +72,21 @@
 void sl_priv_util_eattribute_list_print (GList *eattributes, const gchar *title);
 void sl_priv_util_attribute_list_print (GList *attributes, const gchar *title);
 
+gint sl_priv_util_compare_eattributes (EVCardAttribute *a, EVCardAttribute *b);
+
+gboolean sl_priv_util_eattrlist_name_equal (GList *a, GList *b);
+gboolean sl_priv_util_eattribute_equal (EVCardAttribute *a, EVCardAttribute *b);
+gboolean sl_priv_util_eattrlist_modified (GList *a, GList *b);
+
+void sl_priv_util_list_set_diff (GList *a, GList *b, GEqualFunc equal, GList **added, GList **removed);
+void sl_priv_util_list_set_diff_full (GList *a, GList *b, GEqualFunc is_equal, GEqualFunc is_modified, GList **added, GList **removed, GList **modified, GList **rest);
+
+GList *sl_priv_util_eattribute_flat_to_deep_list (GList *flat);
+void sl_priv_util_eattribute_deep_list_free (GList *deep);
+
+GList *sl_priv_util_strsplit_list (gchar *string, gchar *delimiter, gint max_tokens);
+gchar *sl_priv_util_strjoin_list (gchar *seperator, GList *strings);
+GList *sl_priv_util_strv_to_list (gchar **strv);
+gchar **sl_priv_util_list_to_strv (GList *strings);
+
 #endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]