From 92ed2019e4948f1feb32d9c3ecfb0455323bbe3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Sch=C3=B6bel?= <jonathan@xn--schbel-yxa.info> Date: Mon, 13 Mar 2023 20:23:14 +0100 Subject: [PATCH] Fragment: added parent Every fragment has a parent now, this is useful for both traversing the tree and checking for cycles when a node is added, which would cause problems, like freeing things twice or similar nice bugs. Both wouldn't be possible otherwise. These features are not implemented yet. --- sefht.geany | 14 ++++++------ src/lib/sefht/fragment.c | 10 ++++++++- src/lib/sefht/fragment.h | 4 ++++ src/lib/sefht/fragment_class.c | 41 +++++++++++++++++++++++++++++----- src/lib/sefht/fragment_data.c | 6 +++-- src/lib/sefht/node_fragment.c | 17 +++++++++++--- src/lib/sefht/node_fragment.h | 6 +++++ tests/test_node_fragment.c | 15 +++++++++++++ 8 files changed, 94 insertions(+), 19 deletions(-) diff --git a/sefht.geany b/sefht.geany index 49a3bad..d24bc35 100644 --- a/sefht.geany +++ b/sefht.geany @@ -37,12 +37,12 @@ FILE_NAME_4=1593;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fpr FILE_NAME_5=901;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fcms.h;0;8 FILE_NAME_6=2921;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fdata.c;0;8 FILE_NAME_7=904;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fdata.h;0;8 -FILE_NAME_8=1185;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ffragment.c;0;8 -FILE_NAME_9=916;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ffragment.h;0;8 -FILE_NAME_10=1975;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ffragment_data.c;0;8 -FILE_NAME_11=2173;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=7399;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=931;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_8=1550;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ffragment.c;0;8 +FILE_NAME_9=1562;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ffragment.h;0;8 +FILE_NAME_10=2022;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ffragment_data.c;0;8 +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=6660;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=2360;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=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_15=904;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext.h;0;8 FILE_NAME_16=1779;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator.c;0;8 @@ -56,7 +56,7 @@ FILE_NAME_23=1078;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fp FILE_NAME_24=290;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2FMakefile.am;0;8 FILE_NAME_25=1085;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_cms.c;0;8 FILE_NAME_26=3283;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_data.c;0;8 -FILE_NAME_27=15178;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_node_fragment.c;0;8 +FILE_NAME_27=9757;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_node_fragment.c;0;8 FILE_NAME_28=11068;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_text.c;0;8 FILE_NAME_29=5744;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator.c;0;8 FILE_NAME_30=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/fragment.c b/src/lib/sefht/fragment.c index 6a306bd..72d4707 100644 --- a/src/lib/sefht/fragment.c +++ b/src/lib/sefht/fragment.c @@ -27,11 +27,12 @@ #include "status.h" #include "text.h" +#include "node_fragment.h" #include "fragment.h" -#include "fragment_data.c" +#include "fragment_class.c" /*@null@*/ /*@only@*/ @@ -54,6 +55,13 @@ SH_Fragment_free (/*@only@*/ struct SH_Fragment * fragment) return; } +bool +SH_Fragment_is_orphan (const struct SH_Fragment * fragment) + /*@*/ +{ + return get_parent (fragment) == NULL; +} + /*@null@*/ /*@only@*/ SH_Text * diff --git a/src/lib/sefht/fragment.h b/src/lib/sefht/fragment.h index f2602e8..b55542c 100644 --- a/src/lib/sefht/fragment.h +++ b/src/lib/sefht/fragment.h @@ -58,6 +58,10 @@ SH_Fragment_free (/*@only@*/ SH_Fragment * fragment) /*@modifies fragment@*/ /*@releases fragment@*/; +bool +SH_Fragment_is_orphan (const SH_Fragment * fragment) + /*@*/; + /*@null@*/ /*@only@*/ SH_Text * diff --git a/src/lib/sefht/fragment_class.c b/src/lib/sefht/fragment_class.c index 3a478d1..8fd9a41 100644 --- a/src/lib/sefht/fragment_class.c +++ b/src/lib/sefht/fragment_class.c @@ -41,18 +41,24 @@ static inline void init_fragment (/*@out@*/ struct SH_Fragment * fragment, - /*@dependent@*/ SH_Data * data, const enum SH_FRAGMENT_TYPE type, /*@shared@*/ - const struct fragment_methods * const methods) - /*@modifies fragment->data@*/ + const struct fragment_methods * const methods, + /*@dependent@*/ SH_Data * data, + /*@null@*/ /*@dependent@*/ + struct SH_NodeFragment * parent) /*@modifies fragment->type@*/ /*@modifies fragment->methods@*/ + /*@modifies fragment->data@*/ + /*@modifies fragment->parent@*/ { - fragment->data = data; fragment->type = type; fragment->methods = methods; + fragment->data = data; + + fragment->parent = parent; + return; } @@ -70,14 +76,18 @@ static inline void copy_fragment (/*@out@*/ struct SH_Fragment * copy, const struct SH_Fragment * fragment) - /*@modifies copy->data@*/ /*@modifies copy->type@*/ /*@modifies copy->methods@*/ + /*@modifies copy->data@*/ + /*@modifies copy->parent@*/ { - copy->data = fragment->data; copy->type = fragment->type; copy->methods = fragment->methods; + copy->data = fragment->data; + + copy->parent = NULL; + return; } @@ -89,5 +99,24 @@ get_type (const struct SH_Fragment * fragment) return fragment->type; } +static inline +/*@null@*/ +/*@dependent@*/ +struct SH_NodeFragment * +get_parent (const struct SH_Fragment * fragment) +{ + return fragment->parent; +} + +static inline +void +set_parent (struct SH_Fragment * fragment, + /*@null@*/ /*@dependent@*/ struct SH_NodeFragment * parent) + /*@modifies fragment->parent@*/ +{ + fragment->parent = parent; + return; +} + #endif /* SEFHT_COMPILATION */ #endif /* SEFHT_FRAGMENT_CLASS_C */ diff --git a/src/lib/sefht/fragment_data.c b/src/lib/sefht/fragment_data.c index f55a71c..617f629 100644 --- a/src/lib/sefht/fragment_data.c +++ b/src/lib/sefht/fragment_data.c @@ -76,10 +76,12 @@ struct fragment_methods struct SH_Fragment { - /*@dependent@*/ SH_Data * data; - enum SH_FRAGMENT_TYPE type; /*@shared@*/ const struct fragment_methods * methods; + + /*@dependent@*/ SH_Data * data; + + /*@null@*/ /*@dependent@*/ struct SH_NodeFragment * parent; }; #endif /* SEFHT_COMPILATION */ diff --git a/src/lib/sefht/node_fragment.c b/src/lib/sefht/node_fragment.c index c9a518d..d3dcf04 100644 --- a/src/lib/sefht/node_fragment.c +++ b/src/lib/sefht/node_fragment.c @@ -49,7 +49,7 @@ struct SH_NodeFragment /*@only@*/ char * tag; size_t child_n; - struct SH_Fragment ** childs; + /*@only@*/ struct SH_Fragment ** childs; }; #define OPEN_TAG_BEGIN "<" @@ -100,7 +100,7 @@ SH_NodeFragment_new (const char * tag, return NULL; } - init_fragment (&(fragment->base), data, NODE, &methods); + init_fragment (&(fragment->base), NODE, &methods, data, NULL); fragment->tag = strdup (tag); if (fragment->tag == NULL) @@ -146,9 +146,10 @@ SH_NodeFragment_raw_new (/*@only@*/ char * tag, return NULL; } - init_fragment (&(fragment->base), data, NODE, &methods); + init_fragment (&(fragment->base), NODE, &methods, data, NULL); fragment->tag = tag; + fragment->child_n = 0; fragment->childs = malloc (0); @@ -296,6 +297,7 @@ SH_NodeFragment_deepcopy (const struct SH_NodeFragment * fragment, } copy->childs[index] = child; + child->parent = copy; } set_success (status); @@ -353,6 +355,15 @@ SH_NodeFragment_raw_get_tag (const struct SH_NodeFragment * fragment) return get_tag (fragment); } +/*@null@*/ +/*@dependent@*/ +struct SH_NodeFragment * +SH_Fragment_get_parent (const struct SH_Fragment * fragment) + /*@*/ +{ + return get_parent (fragment); +} + /*@null@*/ /*@observer@*/ struct SH_Fragment * diff --git a/src/lib/sefht/node_fragment.h b/src/lib/sefht/node_fragment.h index 46be532..f325428 100644 --- a/src/lib/sefht/node_fragment.h +++ b/src/lib/sefht/node_fragment.h @@ -80,6 +80,12 @@ bool SH_Fragment_is_NodeFragment (const SH_Fragment * fragment) /*@*/; +/*@null@*/ +/*@dependent@*/ +SH_NodeFragment * +SH_Fragment_get_parent (const SH_Fragment * fragment) + /*@*/; + /*@null@*/ /*@only@*/ char * diff --git a/tests/test_node_fragment.c b/tests/test_node_fragment.c index 6c53371..23cf298 100644 --- a/tests/test_node_fragment.c +++ b/tests/test_node_fragment.c @@ -45,6 +45,7 @@ START_TEST(test_node_fragment) fragment = SH_NodeFragment_new (tag, data, NULL); ck_assert_int_ne ((long int) fragment, (long int) NULL); + ck_assert_ptr_eq (NULL, fragment->parent); ck_assert_str_eq (((struct SH_NodeFragment *) fragment)->tag, tag); SH_Fragment_free (fragment); @@ -55,6 +56,7 @@ START_TEST(test_node_fragment) ck_assert_int_ne ((long int) fragment, (long int) NULL); ck_assert_int_eq (status.status, SUCCESS); + ck_assert_ptr_eq (NULL, fragment->parent); ck_assert_str_eq (((struct SH_NodeFragment *) fragment)->tag, tag); SH_Fragment_free (fragment); @@ -77,6 +79,7 @@ START_TEST(test_node_fragment_raw_new) fragment = SH_NodeFragment_raw_new (tag1, data, NULL); ck_assert_int_ne ((long int) fragment, (long int) NULL); + ck_assert_ptr_eq (NULL, fragment->parent); ck_assert_ptr_eq (((struct SH_NodeFragment *) fragment)->tag, tag1); SH_Fragment_free (fragment); @@ -87,6 +90,7 @@ START_TEST(test_node_fragment_raw_new) ck_assert_int_ne ((long int) fragment, (long int) NULL); ck_assert_int_eq (status.status, SUCCESS); + ck_assert_ptr_eq (NULL, fragment->parent); ck_assert_ptr_eq (((struct SH_NodeFragment *) fragment)->tag, tag2); SH_Fragment_free (fragment); @@ -112,6 +116,7 @@ START_TEST(test_node_fragment_copy) ck_assert_ptr_ne (copy, NULL); ck_assert_ptr_ne (fragment, copy); + ck_assert_ptr_eq (NULL, copy->parent); ck_assert_str_eq (((struct SH_NodeFragment *) fragment)->tag, ((struct SH_NodeFragment *) copy)->tag); ck_assert_int_eq (((struct SH_NodeFragment *) copy)->child_n, 0); @@ -128,6 +133,7 @@ START_TEST(test_node_fragment_copy) ck_assert_ptr_ne (copy, NULL); ck_assert_ptr_ne (fragment, copy); + ck_assert_ptr_eq (NULL, copy->parent); ck_assert_str_eq (((struct SH_NodeFragment *) fragment)->tag, ((struct SH_NodeFragment *) copy)->tag); ck_assert_int_eq (((struct SH_NodeFragment *) copy)->child_n, 0); @@ -150,6 +156,7 @@ check_childs (struct SH_NodeFragment * fragment, struct SH_NodeFragment * copy) { ck_assert_ptr_ne (((struct SH_NodeFragment *) fragment->childs[index]), ((struct SH_NodeFragment *) copy->childs[index])); + ck_assert_ptr_eq (copy, get_parent (copy->childs[index])); ck_assert_str_eq (((struct SH_NodeFragment *) fragment->childs[index])->tag, ((struct SH_NodeFragment *) copy->childs[index])->tag); ck_assert_int_eq (((struct SH_NodeFragment *) fragment->childs[index])->child_n, @@ -206,6 +213,7 @@ START_TEST(test_node_fragment_deepcopy) ck_assert_ptr_ne (copy, NULL); ck_assert_ptr_ne (fragment, copy); + ck_assert_ptr_eq (NULL, copy->parent); ck_assert_str_eq (((struct SH_NodeFragment *) fragment)->tag, ((struct SH_NodeFragment *) copy)->tag); ck_assert_int_eq (((struct SH_NodeFragment *) fragment)->child_n, @@ -225,6 +233,7 @@ START_TEST(test_node_fragment_deepcopy) ck_assert_ptr_ne (copy, NULL); ck_assert_ptr_ne (fragment, copy); + ck_assert_ptr_eq (NULL, copy->parent); ck_assert_str_eq (((struct SH_NodeFragment *) fragment)->tag, ((struct SH_NodeFragment *) copy)->tag); ck_assert_int_eq (((struct SH_NodeFragment *) fragment)->child_n, @@ -307,6 +316,9 @@ START_TEST(test_node_fragment_child) ck_assert_ptr_eq (((struct SH_NodeFragment *) parent)->childs[0], child1); + /* TODO: not implemented yet. */ + //~ ck_assert_ptr_eq (parent, get_parent (child1)); + /* with error */ ck_assert_int_eq (((struct SH_NodeFragment *) parent)->child_n, 1); @@ -320,6 +332,9 @@ START_TEST(test_node_fragment_child) ck_assert_ptr_eq (((struct SH_NodeFragment *) parent)->childs[1], child2); + /* TODO: not implemented yet. */ + //~ ck_assert_ptr_eq (parent, get_parent (child2)); + SH_Fragment_free (parent); SH_Data_free (data); -- GitLab