From 86d926c5b0c4723c8b238185b8215e350666dce5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonathan=20Sch=C3=B6bel?= <jonathan@xn--schbel-yxa.info>
Date: Fri, 2 Jun 2023 18:26:50 +0200
Subject: [PATCH] Attr: added is_equal method

A method to compare two Attr's for exact equality was added both to
internal and external methods.
---
 sefht.geany                 | 10 +++----
 src/lib/sefht/attr.c        |  8 ++++++
 src/lib/sefht/attr.h        |  4 +++
 src/lib/sefht/attr_static.c | 12 ++++++++
 tests/test_attr.c           | 57 +++++++++++++++++++++++++++++++++++++
 5 files changed, 86 insertions(+), 5 deletions(-)

diff --git a/sefht.geany b/sefht.geany
index 1f7d93b..6bf9294 100644
--- a/sefht.geany
+++ b/sefht.geany
@@ -28,7 +28,7 @@ long_line_behaviour=1
 long_line_column=72
 
 [files]
-current_page=13
+current_page=32
 FILE_NAME_0=923;Sh;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fconfigure.ac;0;8
 FILE_NAME_1=73;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2FMakefile.am;0;8
 FILE_NAME_2=1143;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fmain.c;0;8
@@ -43,9 +43,9 @@ FILE_NAME_10=2022;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fp
 FILE_NAME_11=2558;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ffragment_class.c;0;8
 FILE_NAME_12=20283;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fnode_fragment.c;0;8
 FILE_NAME_13=6032;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fnode_fragment.h;0;8
-FILE_NAME_14=1393;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fattr.c;0;8
-FILE_NAME_15=2924;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fattr.h;0;8
-FILE_NAME_16=2603;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fattr_static.c;0;8
+FILE_NAME_14=5001;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fattr.c;0;8
+FILE_NAME_15=2988;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fattr.h;0;8
+FILE_NAME_16=3756;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fattr_static.c;0;8
 FILE_NAME_17=1116;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fattr_data.h;0;8
 FILE_NAME_18=25820;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext.c;0;8
 FILE_NAME_19=904;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext.h;0;8
@@ -61,7 +61,7 @@ FILE_NAME_28=533;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2
 FILE_NAME_29=1085;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_cms.c;0;8
 FILE_NAME_30=3283;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_data.c;0;8
 FILE_NAME_31=53309;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_node_fragment.c;0;8
-FILE_NAME_32=12246;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_attr.c;0;8
+FILE_NAME_32=11726;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_attr.c;0;8
 FILE_NAME_33=11068;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_text.c;0;8
 FILE_NAME_34=5744;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator.c;0;8
 FILE_NAME_35=165;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftodo.txt;0;8
diff --git a/src/lib/sefht/attr.c b/src/lib/sefht/attr.c
index bcd7661..4bd8512 100644
--- a/src/lib/sefht/attr.c
+++ b/src/lib/sefht/attr.c
@@ -256,3 +256,11 @@ SH_Attr_raw_set_value (struct SH_Attr * attr,
 	Attr_set_value (attr, value);
 	return;
 }
+
+bool
+SH_Attr_is_equal (const struct SH_Attr * attr1,
+                  const struct SH_Attr * attr2)
+	/*@*/
+{
+	return Attr_is_equal (attr1, attr2);
+}
diff --git a/src/lib/sefht/attr.h b/src/lib/sefht/attr.h
index 60a916e..73a6bfc 100644
--- a/src/lib/sefht/attr.h
+++ b/src/lib/sefht/attr.h
@@ -117,4 +117,8 @@ SH_Attr_raw_set_value (SH_Attr * attr,
                        /*@null@*/ /*@only@*/ char * value)
 	/*@modifies attr@*/;
 
+bool
+SH_Attr_is_equal (const SH_Attr * attr1, const SH_Attr * attr2)
+	/*@*/;
+
 #endif /* SEFHT_ATTR_H */
diff --git a/src/lib/sefht/attr_static.c b/src/lib/sefht/attr_static.c
index 10c5d6b..48b2181 100644
--- a/src/lib/sefht/attr_static.c
+++ b/src/lib/sefht/attr_static.c
@@ -187,4 +187,16 @@ Attr_set_value (struct SH_Attr * attr, /*@null@*/ /*@only@*/ char * value)
 	return;
 }
 
+static inline
+bool
+Attr_is_equal (const struct SH_Attr * attr1,
+               const struct SH_Attr * attr2)
+	/*@*/
+{
+	if (0 != strcmp (attr1->name, attr2->name)) return FALSE;
+	if (NULL == attr1->value) return (NULL == attr2->value);
+	if (NULL == attr2->value) return FALSE;
+	return (0 == strcmp (attr1->value, attr2->value));
+}
+
 #endif /* SEFHT_ATTR_STATIC_C */
diff --git a/tests/test_attr.c b/tests/test_attr.c
index f87a656..91f1e78 100644
--- a/tests/test_attr.c
+++ b/tests/test_attr.c
@@ -465,6 +465,61 @@ START_TEST(test_attr_value_raw)
 }
 END_TEST
 
+START_TEST(test_attr_equal)
+{
+	struct
+	{
+		struct
+		{
+			char * name;
+			char * value;
+		} _[2];
+		bool result;
+	} tests[] =
+	{
+		{{{"name", NULL}, {"name", NULL}}, TRUE},
+		{{{"name", "value"}, {"name", NULL}}, FALSE},
+		{{{"name", "value"}, {"name", "value"}}, TRUE},
+		{{{"name", "value1"}, {"name", "value2"}}, FALSE},
+		{{{"name1", NULL}, {"name2", NULL}}, FALSE},
+		{{{"name1", "value"}, {"name2", NULL}}, FALSE},
+		{{{"name1", "value"}, {"name2", "value"}}, FALSE},
+		{{{"name1", "value1"}, {"name2", "value2"}}, FALSE}
+	};
+	const size_t size = sizeof (tests) / sizeof (tests[0]);
+	size_t index;
+
+	for (index = 0; index < size; index++)
+	{
+		struct SH_Attr * attr1;
+		struct SH_Attr * attr2;
+		bool result;
+
+		attr1 = SH_Attr_new (tests[index]._[0].name,
+		                     tests[index]._[0].value, NULL);
+		ck_assert_ptr_ne (NULL, attr1);
+
+		attr2 = SH_Attr_new (tests[index]._[1].name,
+		                     tests[index]._[1].value, NULL);
+		ck_assert_ptr_ne (NULL, attr2);
+
+		result = SH_Attr_is_equal (attr1, attr2);
+		ck_assert_int_eq (result, tests[index].result);
+
+		result = SH_Attr_is_equal (attr2, attr1);
+		ck_assert_int_eq (result, tests[index].result);
+
+		result = Attr_is_equal (attr1, attr2);
+		ck_assert_int_eq (result, tests[index].result);
+
+		result = Attr_is_equal (attr2, attr1);
+		ck_assert_int_eq (result, tests[index].result);
+
+		SH_Attr_free (attr1);
+		SH_Attr_free (attr2);
+	}
+}
+
 Suite * test_suite (void)
 {
 	Suite *s;
@@ -498,6 +553,8 @@ Suite * test_suite (void)
 	tcase_add_test (tc_core, test_attr_value_with_status);
 	tcase_add_test (tc_core, test_attr_value_raw);
 
+	tcase_add_test (tc_core, test_attr_equal);
+
 	suite_add_tcase (s, tc_core);
 
 	return s;
-- 
GitLab