hal: Branch 'master'

David Zeuthen david at kemper.freedesktop.org
Mon Oct 9 20:33:37 PDT 2006


 hald/device.c   |  213 ++++++++++++++++++++------------------------------------
 hald/device.h   |    4 -
 hald/property.c |  127 +--------------------------------
 hald/property.h |   46 +++---------
 4 files changed, 93 insertions(+), 297 deletions(-)

New commits:
diff-tree 63a3628bc3f4af4f5cf647dd11fd47a1992491ee (from 952155ea001367144c68c3c0199b0ea82ac52997)
Author: David Zeuthen <davidz at redhat.com>
Date:   Mon Oct 9 23:33:33 2006 -0400

    use a hash table for device properties

diff --git a/hald/device.c b/hald/device.c
index 2c77cef..ad47464 100644
--- a/hald/device.c
+++ b/hald/device.c
@@ -45,7 +45,8 @@ struct _HalDevicePrivate
 	char *udi;	
 	int num_addons;
 	int num_addons_ready;
-	GSList *properties;
+
+	GHashTable *props;
 };
 
 enum {
@@ -72,14 +73,12 @@ hal_device_finalize (GObject *obj)
 	printf ("************* in finalize for udi=%s\n", device->private->udi);
 #endif
 
-
-	g_slist_foreach (device->private->properties, (GFunc) hal_property_free, NULL);
-	g_slist_free (device->private->properties);
-
 	g_free (device->private->udi);
 
 	g_free (device->private);
 
+	g_hash_table_destroy (device->private->props);
+
 	if (parent_class->finalize)
 		parent_class->finalize (obj);
 }
@@ -129,6 +128,11 @@ hal_device_init (HalDevice *device)
 				       temp_device_counter++);
 	device->private->num_addons = 0;
 	device->private->num_addons_ready = 0;
+
+	device->private->props = g_hash_table_new_full (g_str_hash, 
+							g_str_equal, 
+							g_free, 
+							(GDestroyNotify) hal_property_free);
 }
 
 GType
@@ -186,6 +190,8 @@ hal_device_merge_with_rewrite  (HalDevic
 				const char   *target_namespace,
 				const char   *source_namespace)
 {
+#if 0
+#warning FIXME
 	GSList *iter;
 	size_t source_ns_len;
 
@@ -259,29 +265,19 @@ hal_device_merge_with_rewrite  (HalDevic
 	}
 
 	/* device_property_atomic_update_end (); */
-
+#endif
 }
 
-static HalProperty *
+static inline HalProperty *
 hal_device_property_find (HalDevice *device, const char *key)
 {
-	GSList *iter;
-
 	g_return_val_if_fail (device != NULL, NULL);
 	g_return_val_if_fail (key != NULL, NULL);
 
-	for (iter = device->private->properties; iter != NULL; iter = iter->next) {
-		HalProperty *p = iter->data;
-
-		if (strcmp (hal_property_get_key (p), key) == 0) {
-			return p;
-		}
-	}
-
-	return NULL;
+	return g_hash_table_lookup (device->private->props, key);
 }
 
-static GSList *
+static inline GSList *
 hal_device_property_get_strlist (HalDevice    *device, 
 				 const char   *key)
 {
@@ -291,7 +287,6 @@ hal_device_property_get_strlist (HalDevi
 	g_return_val_if_fail (key != NULL, NULL);
 
 	prop = hal_device_property_find (device, key);
-
 	if (prop != NULL)
 		return hal_property_get_strlist (prop);
 	else
@@ -390,6 +385,8 @@ out:
 void
 hal_device_merge (HalDevice *target, HalDevice *source)
 {
+#if 0
+#warning TODO
 	GSList *iter;
 	GSList *caps;
 
@@ -458,72 +455,7 @@ hal_device_merge (HalDevice *target, Hal
 		if (!hal_device_has_capability (target, iter->data))
 			hal_device_add_capability (target, iter->data);
 	}
-}
-
-gboolean
-hal_device_matches (HalDevice *device1, HalDevice *device2,
-		    const char *namespace)
-{
-	int len;
-	GSList *iter;
-
-	len = strlen (namespace);
-
-	for (iter = device1->private->properties; iter != NULL; iter = iter->next) {
-		HalProperty *p;
-		const char *key;
-		int type;
-
-		p = (HalProperty *) iter->data;
-		key = hal_property_get_key (p);
-		type = hal_property_get_type (p);
-
-		if (strncmp (key, namespace, len) != 0)
-			continue;
-
-		if (!hal_device_has_property (device2, key))
-			return FALSE;
-
-		switch (type) {
-
-		case HAL_PROPERTY_TYPE_STRING:
-			if (strcmp (hal_property_get_string (p),
-				    hal_device_property_get_string (device2,
-								    key)) != 0)
-				return FALSE;
-			break;
-
-		case HAL_PROPERTY_TYPE_INT32:
-			if (hal_property_get_int (p) !=
-			    hal_device_property_get_int (device2, key))
-				return FALSE;
-			break;
-
-		case HAL_PROPERTY_TYPE_UINT64:
-			if (hal_property_get_uint64 (p) !=
-				hal_device_property_get_uint64 (device2, key))
-				return FALSE;
-			break;
-
-		case HAL_PROPERTY_TYPE_BOOLEAN:
-			if (hal_property_get_bool (p) !=
-			    hal_device_property_get_bool (device2, key))
-				return FALSE;
-			break;
-
-		case HAL_PROPERTY_TYPE_DOUBLE:
-			if (hal_property_get_double (p) !=
-			    hal_device_property_get_double (device2, key))
-				return FALSE;
-			break;
-
-		default:
-			HAL_WARNING (("Unknown property type %d", type));
-			break;
-		}
-	}
-
-	return TRUE;
+#endif
 }
 
 const char *
@@ -574,7 +506,7 @@ hal_device_num_properties (HalDevice *de
 {
 	g_return_val_if_fail (device != NULL, -1);
 
-	return g_slist_length (device->private->properties);
+	return g_hash_table_size (device->private->props);
 }
 
 gboolean
@@ -598,25 +530,42 @@ hal_device_property_to_string (HalDevice
 	return hal_property_to_string (prop);
 }
 
+typedef struct 
+{
+	HalDevice *device;
+	HalDevicePropertyForeachFn callback;
+	gpointer user_data;
+} hdpfe_ud_t;
+
+static void
+hdpfe (gpointer key,
+       gpointer value,
+       gpointer user_data)
+{
+	hdpfe_ud_t *c;
+	HalProperty *prop;
+
+	c = (hdpfe_ud_t *) user_data;
+	prop = (HalProperty *) value;
+
+	c->callback (c->device, (const char *) key, c->user_data);
+}
+
 void
 hal_device_property_foreach (HalDevice *device,
 			     HalDevicePropertyForeachFn callback,
 			     gpointer user_data)
 {
-	GSList *iter;
+	hdpfe_ud_t c;
 
 	g_return_if_fail (device != NULL);
 	g_return_if_fail (callback != NULL);
 
-	for (iter = device->private->properties; iter != NULL; iter = iter->next) {
-		HalProperty *p = iter->data;
-		gboolean cont;
-
-		cont = callback (device, hal_property_get_key (p), user_data);
+	c.device = device;
+	c.callback = callback;
+	c.user_data = user_data;
 
-		if (cont == FALSE)
-			return;
-	}
+	g_hash_table_foreach (device->private->props, hdpfe, &c);
 }
 
 int
@@ -803,10 +752,10 @@ hal_device_property_set_string (HalDevic
 			       key, FALSE, FALSE);
 
 	} else {
+		prop = hal_property_new (HAL_PROPERTY_TYPE_STRING);
+		hal_property_set_string (prop, value);
 
-		prop = hal_property_new_string (key, value);
-
-		device->private->properties = g_slist_prepend (device->private->properties, prop);
+		g_hash_table_insert (device->private->props, g_strdup (key), prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -838,9 +787,9 @@ hal_device_property_set_int (HalDevice *
 			       key, FALSE, FALSE);
 
 	} else {
-		prop = hal_property_new_int (key, value);
-
-		device->private->properties = g_slist_prepend (device->private->properties, prop);
+		prop = hal_property_new (HAL_PROPERTY_TYPE_INT32);
+		hal_property_set_int (prop, value);
+		g_hash_table_insert (device->private->props, g_strdup (key), prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -872,9 +821,9 @@ hal_device_property_set_uint64 (HalDevic
 			       key, FALSE, FALSE);
 
 	} else {
-		prop = hal_property_new_uint64 (key, value);
-
-		device->private->properties = g_slist_prepend (device->private->properties, prop);
+		prop = hal_property_new (HAL_PROPERTY_TYPE_UINT64);
+		hal_property_set_uint64 (prop, value);
+		g_hash_table_insert (device->private->props, g_strdup (key), prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -906,9 +855,9 @@ hal_device_property_set_bool (HalDevice 
 			       key, FALSE, FALSE);
 
 	} else {
-		prop = hal_property_new_bool (key, value);
-
-		device->private->properties = g_slist_prepend (device->private->properties, prop);
+		prop = hal_property_new (HAL_PROPERTY_TYPE_BOOLEAN);
+		hal_property_set_bool (prop, value);
+		g_hash_table_insert (device->private->props, g_strdup (key), prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -940,9 +889,9 @@ hal_device_property_set_double (HalDevic
 			       key, FALSE, FALSE);
 
 	} else {
-		prop = hal_property_new_double (key, value);
-
-		device->private->properties = g_slist_prepend (device->private->properties, prop);
+		prop = hal_property_new (HAL_PROPERTY_TYPE_DOUBLE);
+		hal_property_set_double (prop, value);
+		g_hash_table_insert (device->private->props, g_strdup (key), prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -989,26 +938,19 @@ hal_device_copy_property (HalDevice *fro
 gboolean
 hal_device_property_remove (HalDevice *device, const char *key)
 {
-	HalProperty *prop;
-
-	prop = hal_device_property_find (device, key);
-
-	if (prop == NULL)
-		return FALSE;
-
-	device->private->properties = g_slist_remove (device->private->properties, prop);
-
-	hal_property_free (prop);
-
-	g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
-		       key, TRUE, FALSE);
-
-	return TRUE;
+	if (g_hash_table_remove (device->private->props, key)) {
+		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+			       key, TRUE, FALSE);
+		return TRUE;
+	}
+	return FALSE;
 }
 
 void
 hal_device_print (HalDevice *device)
 {
+#if 0
+#warning TODO
 	GSList *iter;
 
         fprintf (stderr, "device udi = %s\n", hal_device_get_udi (device));
@@ -1056,6 +998,7 @@ hal_device_print (HalDevice *device)
                 }
         }
         fprintf (stderr, "\n");
+#endif
 }
 
 const char *
@@ -1097,10 +1040,10 @@ hal_device_property_strlist_append (HalD
 			       key, FALSE, FALSE);
 
 	} else {
-		prop = hal_property_new_strlist (key);
+		prop = hal_property_new (HAL_PROPERTY_TYPE_STRLIST);
 		hal_property_strlist_append (prop, value);
 
-		device->private->properties = g_slist_prepend (device->private->properties, prop);
+		g_hash_table_insert (device->private->props, g_strdup (key), prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -1129,10 +1072,10 @@ hal_device_property_strlist_prepend (Hal
 			       key, FALSE, FALSE);
 
 	} else {
-		prop = hal_property_new_strlist (key);
+		prop = hal_property_new (HAL_PROPERTY_TYPE_STRLIST);
 		hal_property_strlist_prepend (prop, value);
 
-		device->private->properties = g_slist_prepend (device->private->properties, prop);
+		g_hash_table_insert (device->private->props, g_strdup (key), prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -1176,13 +1119,11 @@ hal_device_property_strlist_clear (HalDe
 	prop = hal_device_property_find (device, key);
 
 	if (prop == NULL) {
-		prop = hal_property_new_strlist (key);
-
-		device->private->properties = g_slist_prepend (device->private->properties, prop);
+		prop = hal_property_new (HAL_PROPERTY_TYPE_STRLIST);
+		g_hash_table_insert (device->private->props, g_strdup (key), prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
-
 		return TRUE;
 	}
 
@@ -1223,10 +1164,10 @@ hal_device_property_strlist_add (HalDevi
 		}
 
 	} else {
-		prop = hal_property_new_strlist (key);
+		prop = hal_property_new (HAL_PROPERTY_TYPE_STRLIST);
 		hal_property_strlist_prepend (prop, value);
 
-		device->private->properties = g_slist_prepend (device->private->properties, prop);
+		g_hash_table_insert (device->private->props, g_strdup (key), prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
diff --git a/hald/device.h b/hald/device.h
index 4ba52f3..c221323 100644
--- a/hald/device.h
+++ b/hald/device.h
@@ -98,10 +98,6 @@ void          hal_device_merge_with_rewr
 					      const char   *target_namespace,
 					      const char   *source_namespace);
 
-gboolean      hal_device_matches             (HalDevice    *device1,
-					      HalDevice    *device2,
-					      const char   *namespace);
-
 const char   *hal_device_get_udi             (HalDevice    *device);
 void          hal_device_set_udi             (HalDevice    *device,
 					      const char   *udi);
diff --git a/hald/property.c b/hald/property.c
index 5f89e78..9455418 100644
--- a/hald/property.c
+++ b/hald/property.c
@@ -36,8 +36,6 @@
 #include "property.h"
 
 struct _HalProperty {
-	char *key;
-
 	int type;
 	union {
 		char *str_value;
@@ -52,8 +50,6 @@ struct _HalProperty {
 void
 hal_property_free (HalProperty *prop)
 {
-	g_free (prop->key);
-
 	if (prop->type == HAL_PROPERTY_TYPE_STRING) {
 		g_free (prop->v.str_value);
 	} else if (prop->type == HAL_PROPERTY_TYPE_STRLIST) {
@@ -63,114 +59,22 @@ hal_property_free (HalProperty *prop)
 		}
 		g_slist_free (prop->v.strlist_value);
 	}
-
 	g_free (prop);
 }
 
-static inline HalProperty *
-hal_property_new (void)
-{
-	HalProperty *prop;
-	prop = g_new0 (HalProperty, 1); 
-	return prop;
-}
-
-HalProperty *
-hal_property_new_string (const char *key, const char *value)
-{
-	HalProperty *prop;
-	char *endchar;
-	gboolean validated = TRUE;
-
-	prop = hal_property_new ();
-
-	prop->type = HAL_PROPERTY_TYPE_STRING;
-	prop->key = g_strdup (key);
-	prop->v.str_value = g_strdup (value != NULL ? value : "");
-
-	while (!g_utf8_validate (prop->v.str_value, -1,
-				 (const char **) &endchar)) {
-		validated = FALSE;
-		*endchar = '?';
-	}
-
-	if (!validated) {
-		HAL_WARNING (("Key '%s' has invalid UTF-8 string '%s'",
-			      key, prop->v.str_value));
-	}
-
-	return prop;
-}
-
 HalProperty *
-hal_property_new_int (const char *key, dbus_int32_t value)
+hal_property_new (int type)
 {
 	HalProperty *prop;
-
-	prop = hal_property_new ();
-
-	prop->type = HAL_PROPERTY_TYPE_INT32;
-	prop->key = g_strdup (key);
-	prop->v.int_value = value;
-
+	prop = g_new0 (HalProperty, 1);
+	prop->type = type;
 	return prop;
 }
 
-HalProperty *
-hal_property_new_uint64 (const char *key, dbus_uint64_t value)
-{
-	HalProperty *prop;
-
-	prop = hal_property_new ();
-
-	prop->type = HAL_PROPERTY_TYPE_UINT64;
-	prop->key = g_strdup (key);
-	prop->v.uint64_value = value;
-
-	return prop;
-}
-
-HalProperty *
-hal_property_new_bool (const char *key, dbus_bool_t value)
-{
-	HalProperty *prop;
-
-	prop = hal_property_new ();
-
-	prop->type = HAL_PROPERTY_TYPE_BOOLEAN;
-	prop->key = g_strdup (key);
-	prop->v.bool_value = value;
-
-	return prop;
-}
-
-HalProperty *
-hal_property_new_double (const char *key, double value)
-{
-	HalProperty *prop;
-
-	prop = hal_property_new ();
-
-	prop->type = HAL_PROPERTY_TYPE_DOUBLE;
-	prop->key = g_strdup (key);
-	prop->v.double_value = value;
-
-	return prop;
-}
-
-const char *
-hal_property_get_key (HalProperty *prop)
-{
-	g_return_val_if_fail (prop != NULL, NULL);
-
-	return prop->key;
-}
-
 int
 hal_property_get_type (HalProperty *prop)
 {
 	g_return_val_if_fail (prop != NULL, HAL_PROPERTY_TYPE_INVALID);
-
 	return prop->type;
 }
 
@@ -179,7 +83,6 @@ hal_property_get_string (HalProperty *pr
 {
 	g_return_val_if_fail (prop != NULL, NULL);
 	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRING, NULL);
-
 	return prop->v.str_value;
 }
 
@@ -188,7 +91,6 @@ hal_property_get_int (HalProperty *prop)
 {
 	g_return_val_if_fail (prop != NULL, -1);
 	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_INT32, -1);
-
 	return prop->v.int_value;
 }
 
@@ -197,7 +99,6 @@ hal_property_get_uint64 (HalProperty *pr
 {
 	g_return_val_if_fail (prop != NULL, -1);
 	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_UINT64, -1);
-
 	return prop->v.uint64_value;
 }
 
@@ -206,7 +107,6 @@ hal_property_get_bool (HalProperty *prop
 {
 	g_return_val_if_fail (prop != NULL, FALSE);
 	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_BOOLEAN, FALSE);
-
 	return prop->v.bool_value;
 }
 
@@ -290,8 +190,7 @@ hal_property_set_string (HalProperty *pr
 	}
 
 	if (!validated) {
-		HAL_WARNING (("Key '%s' has invalid UTF-8 string '%s'",
-			      prop->key, value));
+		HAL_WARNING (("Property has invalid UTF-8 string '%s'", value));
 	}
 }
 
@@ -301,7 +200,6 @@ hal_property_set_int (HalProperty *prop,
 	g_return_if_fail (prop != NULL);
 	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_INT32 ||
 			  prop->type == HAL_PROPERTY_TYPE_INVALID);
-
 	prop->type = HAL_PROPERTY_TYPE_INT32;
 	prop->v.int_value = value;
 }
@@ -312,7 +210,6 @@ hal_property_set_uint64 (HalProperty *pr
 	g_return_if_fail (prop != NULL);
 	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_UINT64 ||
 			  prop->type == HAL_PROPERTY_TYPE_INVALID);
-
 	prop->type = HAL_PROPERTY_TYPE_UINT64;
 	prop->v.uint64_value = value;
 }
@@ -323,7 +220,6 @@ hal_property_set_bool (HalProperty *prop
 	g_return_if_fail (prop != NULL);
 	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_BOOLEAN ||
 			  prop->type == HAL_PROPERTY_TYPE_INVALID);
-
 	prop->type = HAL_PROPERTY_TYPE_BOOLEAN;
 	prop->v.bool_value = value;
 }
@@ -334,25 +230,10 @@ hal_property_set_double (HalProperty *pr
 	g_return_if_fail (prop != NULL);
 	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_DOUBLE ||
 			  prop->type == HAL_PROPERTY_TYPE_INVALID);
-
 	prop->type = HAL_PROPERTY_TYPE_DOUBLE;
 	prop->v.double_value = value;
 }
 
-HalProperty *
-hal_property_new_strlist (const char *key)
-{
-	HalProperty *prop;
-
-	prop = hal_property_new ();
-
-	prop->type = HAL_PROPERTY_TYPE_STRLIST;
-	prop->key = g_strdup (key);
-	prop->v.strlist_value = NULL;
-
-	return prop;
-}
-
 GSList *
 hal_property_get_strlist (HalProperty *prop)
 {
diff --git a/hald/property.h b/hald/property.h
index 07d9597..8a8f78e 100644
--- a/hald/property.h
+++ b/hald/property.h
@@ -33,19 +33,8 @@ typedef struct _HalProperty HalProperty;
 
 void          hal_property_free               (HalProperty  *prop);
 
-HalProperty *hal_property_new_string          (const char   *key,
-					       const char   *value);
-HalProperty *hal_property_new_int             (const char   *key,
-					       dbus_int32_t  value);
-HalProperty *hal_property_new_uint64          (const char   *key,
-					       dbus_uint64_t value);
-HalProperty *hal_property_new_bool            (const char   *key,
-					       dbus_bool_t   value);
-HalProperty *hal_property_new_double          (const char   *key,
-					       double        value);
-HalProperty *hal_property_new_strlist         (const char   *key);
+HalProperty *hal_property_new                 (int type);
 
-const char   *hal_property_get_key            (HalProperty  *prop);
 int           hal_property_get_type           (HalProperty  *prop);
 char         *hal_property_to_string          (HalProperty  *prop);
 
@@ -56,28 +45,17 @@ dbus_bool_t   hal_property_get_bool     
 double        hal_property_get_double         (HalProperty  *prop);
 GSList       *hal_property_get_strlist        (HalProperty  *prop);
 
-void          hal_property_set_string         (HalProperty  *prop,
-					       const char   *value);
-void          hal_property_set_int            (HalProperty  *prop,
-					       dbus_int32_t  value);
-void          hal_property_set_uint64         (HalProperty  *prop,
-					       dbus_uint64_t value);
-void          hal_property_set_bool           (HalProperty  *prop,
-					       dbus_bool_t   value);
-void          hal_property_set_double         (HalProperty  *prop,
-					       double        value);
-gboolean      hal_property_strlist_append     (HalProperty  *prop,
-					       const char   *value);
-gboolean      hal_property_strlist_prepend    (HalProperty  *prop,
-					       const char   *value);
-gboolean      hal_property_strlist_remove_elem (HalProperty  *prop,
-					        guint index);
-
-gboolean      hal_property_strlist_add        (HalProperty  *prop,
-					       const char *value);
-gboolean      hal_property_strlist_remove     (HalProperty  *prop,
-					       const char *value);
-gboolean      hal_property_strlist_clear      (HalProperty  *prop);
+void          hal_property_set_string          (HalProperty  *prop, const char   *value);
+void          hal_property_set_int             (HalProperty  *prop, dbus_int32_t  value);
+void          hal_property_set_uint64          (HalProperty  *prop, dbus_uint64_t value);
+void          hal_property_set_bool            (HalProperty  *prop, dbus_bool_t   value);
+void          hal_property_set_double          (HalProperty  *prop, double        value);
+gboolean      hal_property_strlist_append      (HalProperty  *prop, const char   *value);
+gboolean      hal_property_strlist_prepend     (HalProperty  *prop, const char   *value);
+gboolean      hal_property_strlist_remove_elem (HalProperty  *prop, guint index);
 
+gboolean      hal_property_strlist_add        (HalProperty  *prop, const char *value);
+gboolean      hal_property_strlist_remove     (HalProperty  *prop, const char *value);
+gboolean      hal_property_strlist_clear      (HalProperty  *prop);
 
 #endif /* PROPERTY_H */


More information about the hal-commit mailing list