Yuri Chornoivan contributed some typo fixes
[pspp] / src / libpspp / string-map.c
index ac32a35869d4e4055e1837c40b3a5d09a20564c9..670154fc5df63cd753d48a1d86d3da217ef89a8d 100644 (file)
@@ -25,6 +25,7 @@
 #include "libpspp/string-set.h"
 
 #include "gl/xalloc.h"
+#include "gl/xmemdup0.h"
 
 static struct string_map_node *string_map_find_node_with_hash (
   const struct string_map *, const char *key, size_t length,
@@ -74,7 +75,7 @@ string_map_node_set_value_nocopy (struct string_map_node *node, char *value)
   node->value = value;
 }
 
-/* Frees NODE and and its key and value.  Ordinarily nodes are owned by
+/* Frees NODE and its key and value.  Ordinarily nodes are owned by
    string_maps, but this function should only be used by a caller that owns
    NODE, such as one that has called string_map_delete_nofree() for the
    node. */
@@ -199,7 +200,8 @@ string_map_insert (struct string_map *map, const char *key, const char *value)
   struct string_map_node *node = string_map_find_node_with_hash (map, key,
                                                                  length, hash);
   if (node == NULL)
-    node = string_map_insert__ (map, xstrdup (key), xstrdup (value), hash);
+    node = string_map_insert__ (map, xmemdup0 (key, length), xstrdup (value),
+                                hash);
   return node;
 }
 
@@ -235,7 +237,8 @@ string_map_replace (struct string_map *map, const char *key, const char *value)
   struct string_map_node *node = string_map_find_node_with_hash (map, key,
                                                                  length, hash);
   if (node == NULL)
-    node = string_map_insert__ (map, xstrdup (key), xstrdup (value), hash);
+    node = string_map_insert__ (map, xmemdup0 (key, length),
+                                xstrdup (value), hash);
   else
     string_map_node_set_value (node, value);
   return node;
@@ -357,6 +360,25 @@ string_map_get_values (const struct string_map *map, struct string_set *values)
   STRING_MAP_FOR_EACH_VALUE (value, node, map)
     string_set_insert (values, value);
 }
+
+/* Returns true if A and B have the same content, false otherwise. */
+bool
+string_map_equals (const struct string_map *a, const struct string_map *b)
+{
+  if (string_map_count (a) != string_map_count (b))
+    return false;
+
+   const struct string_map_node *a_node;
+   STRING_MAP_FOR_EACH_NODE (a_node, a)
+     {
+       const struct string_map_node *b_node = string_map_find_node_with_hash (
+         b, a_node->key, strlen (a_node->key), a_node->hmap_node.hash);
+       if (!b_node || strcmp (a_node->value, b_node->value))
+         return false;
+     }
+
+   return true;
+}
 \f
 static struct string_map_node *
 string_map_find_node_with_hash (const struct string_map *map, const char *key,