From aedf7928ac7bf4bd6a5f2838f4fe1c7d35fffd43 Mon Sep 17 00:00:00 2001 From: Truxilla <149168007+Truxilla@users.noreply.github.com> Date: Mon, 13 Jan 2025 21:59:02 +0100 Subject: [PATCH 1/4] moved everything to the right directories and updated the makefile --- Makefile | 48 ++++++++++++++---- README.md | 3 -- all | Bin 0 -> 64208 bytes .../inlupp2 => demo}/business_logic/backend.h | 2 +- {src/inlupp2 => demo}/business_logic/cart.c | 2 +- {src/inlupp2 => demo}/business_logic/common.c | 2 +- {src/inlupp2 => demo}/business_logic/common.h | 0 {src/inlupp2 => demo}/business_logic/merch.c | 3 +- {src/inlupp2 => demo}/business_logic/shop.c | 2 +- {src/inlupp2 => demo}/coverage.txt | 0 demo/frontend | Bin 0 -> 121352 bytes .../generic_data_structures/common.h | 0 .../generic_data_structures/hash_table.c | 2 +- .../generic_data_structures/hash_table.h | 0 .../hash_table_tests.c | 0 .../generic_data_structures/iterator.h | 0 .../generic_data_structures/linked_list.c | 2 +- .../generic_data_structures/linked_list.h | 0 .../linked_list_tests.c | 0 {src/inlupp2 => demo}/generic_utils/utils.c | 2 +- {src/inlupp2 => demo}/generic_utils/utils.h | 0 {src/inlupp2 => demo}/makefile | 7 +-- {src/inlupp2 => demo}/readme.md | 0 {src/inlupp2 => demo}/tests/backend_tests.c | 3 +- .../user_interface/frontend.c | 2 +- .../user_interface/ui-tests/addMerch.txt | 0 .../ui-tests/addMultipleMerch.txt | 0 .../user_interface/ui-tests/createCart.txt | 0 .../ui-tests/editMerchInShelf.txt | 0 .../user_interface/ui-tests/editOneMerch.txt | 0 .../ui-tests/editOneMerchInStock.txt | 0 .../ui-tests/listMerchPaging.txt | 0 .../ui-tests/quitWithMerchInCart.txt | 0 .../ui-tests/removeCartWithMerch.txt | 0 .../user_interface/ui-tests/removeMany.txt | 0 .../user_interface/ui-tests/removeOne.txt | 0 .../ui-tests/replenishMerch.txt | 0 .../ui-tests/replenishMerchAdv.txt | 0 proj/design_report.md | 47 ----------------- test/test.c | 31 +++++------ 40 files changed, 63 insertions(+), 95 deletions(-) delete mode 100644 README.md create mode 100644 all rename {src/inlupp2 => demo}/business_logic/backend.h (99%) rename {src/inlupp2 => demo}/business_logic/cart.c (99%) rename {src/inlupp2 => demo}/business_logic/common.c (98%) rename {src/inlupp2 => demo}/business_logic/common.h (100%) rename {src/inlupp2 => demo}/business_logic/merch.c (99%) rename {src/inlupp2 => demo}/business_logic/shop.c (97%) rename {src/inlupp2 => demo}/coverage.txt (100%) create mode 100644 demo/frontend rename {src/inlupp2 => demo}/generic_data_structures/common.h (100%) rename {src/inlupp2 => demo}/generic_data_structures/hash_table.c (99%) rename {src/inlupp2 => demo}/generic_data_structures/hash_table.h (100%) rename {src/inlupp2 => demo}/generic_data_structures/hash_table_tests.c (100%) rename {src/inlupp2 => demo}/generic_data_structures/iterator.h (100%) rename {src/inlupp2 => demo}/generic_data_structures/linked_list.c (99%) rename {src/inlupp2 => demo}/generic_data_structures/linked_list.h (100%) rename {src/inlupp2 => demo}/generic_data_structures/linked_list_tests.c (100%) rename {src/inlupp2 => demo}/generic_utils/utils.c (98%) rename {src/inlupp2 => demo}/generic_utils/utils.h (100%) rename {src/inlupp2 => demo}/makefile (89%) rename {src/inlupp2 => demo}/readme.md (100%) rename {src/inlupp2 => demo}/tests/backend_tests.c (99%) rename {src/inlupp2 => demo}/user_interface/frontend.c (99%) rename {src/inlupp2 => demo}/user_interface/ui-tests/addMerch.txt (100%) rename {src/inlupp2 => demo}/user_interface/ui-tests/addMultipleMerch.txt (100%) rename {src/inlupp2 => demo}/user_interface/ui-tests/createCart.txt (100%) rename {src/inlupp2 => demo}/user_interface/ui-tests/editMerchInShelf.txt (100%) rename {src/inlupp2 => demo}/user_interface/ui-tests/editOneMerch.txt (100%) rename {src/inlupp2 => demo}/user_interface/ui-tests/editOneMerchInStock.txt (100%) rename {src/inlupp2 => demo}/user_interface/ui-tests/listMerchPaging.txt (100%) rename {src/inlupp2 => demo}/user_interface/ui-tests/quitWithMerchInCart.txt (100%) rename {src/inlupp2 => demo}/user_interface/ui-tests/removeCartWithMerch.txt (100%) rename {src/inlupp2 => demo}/user_interface/ui-tests/removeMany.txt (100%) rename {src/inlupp2 => demo}/user_interface/ui-tests/removeOne.txt (100%) rename {src/inlupp2 => demo}/user_interface/ui-tests/replenishMerch.txt (100%) rename {src/inlupp2 => demo}/user_interface/ui-tests/replenishMerchAdv.txt (100%) delete mode 100644 proj/design_report.md diff --git a/Makefile b/Makefile index 23e1279..dae4388 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # Define compiler and options C_COMPILER = gcc -C_OPTIONS = -Wall -pedantic -Wextra -g +C_OPTIONS = C_LINK_OPTIONS = -lm CUNIT_LINK = -lcunit C_COVERAGE = gcov -abcfu --coverage @@ -8,29 +8,53 @@ R_COVERAGE = gcovr -r . --html --html-details -o coverage.html # Source and object files REF = src/ref.c -REF_OBJ = src/ref.o TEST_SRC = test/test.c -TEST_OBJ = test/test.o HASH = src/lib/lib_hash_table.c -HASH_OBJ = src/lib/lib_hash_table.o LIST = src/lib/lib_linked_list.c -LIST_OBJ = src/lib/lib_linked_list.o + + +# Object files +OBJ_DIR = obj +SRC_DIR = src +LIB_DIR = lib +TEST_DIR = test +REF_OBJ = $(OBJ_DIR)/ref.o +TEST_OBJ = $(OBJ_DIR)/$(TEST_DIR)/test.o +HASH_OBJ = $(OBJ_DIR)/$(LIB_DIR)/lib_hash_table.o +LIST_OBJ = $(OBJ_DIR)/$(LIB_DIR)/lib_linked_list.o # Pattern rule to compile .c files into .o files -%.o: %.c +$(OBJ_DIR)/%.o: src/%.c + $(C_COMPILER) $(C_OPTIONS) -c $< -o $@ + +$(OBJ_DIR)/lib/%.o: src/lib/%.c + $(C_COMPILER) $(C_OPTIONS) -c $< -o $@ + +$(OBJ_DIR)/test/%.o: test/%.c $(C_COMPILER) $(C_OPTIONS) -c $< -o $@ # Target for the reference executable -ref: $(REF_OBJ) $(TEST_OBJ) $(HASH_OBJ) $(LIST_OBJ) +all: $(REF_OBJ) $(TEST_OBJ) $(HASH_OBJ) $(LIST_OBJ) $(C_COMPILER) $(C_LINK_OPTIONS) $(REF_OBJ) $(TEST_OBJ) $(HASH_OBJ) $(LIST_OBJ) -o $@ $(CUNIT_LINK) run: ref valgrind --leak-check=full --show-leak-kinds=all ./ref +demo: + $(MAKE) -C demo start + +memdemo: + $(MAKE) -C demo full_val_frontend + # Target for the test executable -ref_test: $(REF_OBJ) $(TEST_OBJ) $(HASH_OBJ) $(LIST_OBJ) - $(C_COMPILER) $(C_LINK_OPTIONS) $(REF_OBJ) $(TEST_OBJ) $(HASH_OBJ) $(LIST_OBJ) -o $@ $(CUNIT_LINK) - valgrind --leak-check=full --show-leak-kinds=all ./ref_test +test: $(REF_OBJ) $(TEST_OBJ) $(HASH_OBJ) $(LIST_OBJ) + $(C_COMPILER) $(C_LINK_OPTIONS) $(REF_OBJ) $(TEST_OBJ) $(HASH_OBJ) $(LIST_OBJ) -o $(OBJ_DIR)/test/test $(CUNIT_LINK) + $(OBJ_DIR)/test/test + +memtest: $(REF_OBJ) $(TEST_OBJ) $(HASH_OBJ) $(LIST_OBJ) + $(C_COMPILER) $(C_LINK_OPTIONS) $(REF_OBJ) $(TEST_OBJ) $(HASH_OBJ) $(LIST_OBJ) -o $(OBJ_DIR)/test/test $(CUNIT_LINK) + valgrind --leak-check=full --show-leak-kinds=all $(OBJ_DIR)/test/test + gdb: ref gdb ./ref --tui @@ -45,4 +69,6 @@ coverage: cov # Clean up generated files clean: - rm -f src/*.o inlupp2_DONOTTOUCH/generic_data_structures/*.o test/*.o ref* cov* test.c.* \ No newline at end of file + rm -f obj/*.o obj/*/*.o obj/test/test *.gcda *.gcno ref* cov* test.c.* + +.PHONY: demo \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index 236a8d7..0000000 --- a/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# [Your group name here] - -This README file should contain something more useful than this sentence... diff --git a/all b/all new file mode 100644 index 0000000000000000000000000000000000000000..f97bab13a953f089636cccfb45700f4637a6f6ca GIT binary patch literal 64208 zcmeFa33yc1*#~~_Ozz}PGD#-OWCb$pVF^jt3d)iIfdK+U0UH+_LNbs@NMbU>Vnr!I zYZ{~AUPZ-EYw1_9*jkH%EN{2inWR2=Az z!@p7qjxCSa1i&bDiDySiblFttq3k2N6{9pXq>|`*`{)S*Vw8$ow24lms%*!W&rcC} zMrpuJd6fdL#FXJ|(QlMiI`U2FDgiHDA6**$I4AvM&{31C+QNPMFt8T46rJXrg`kyk0{!rvEsV#~{<9!6=%y8v|L zm+$&9hWSD%ueWj7Fa2ngG~V6;GS`1rkV9esaqXpF&wWD*X2h~5}t zqn(Zl;gJ0|EPX%)T&KQF{L8|>Y2|O8dg|j_u6`}>>Z*6Htm;#3pZO1T_xSladgauP zg3p0~p86N{f}etZZxjd7cojuYd{*|-zq^MxmNU3ZlZi9@|C zbC!OOfsC?F_Q#_xO=4)XrQhnowU&M(M-#yYOF!=qm<#f(rQf>lY_{~1Y~yp6rQh%! z!M0iYF#zUgyQN=lSs1p{(w}HzE6OfQKL*zP?6>qMo4ty1$kK1b1c47*`cp0V|Ed1R z1OM^Be?0IX5B&ej17}nEeeG*IrTaRxcbXK%cisM=t?RI_?K%Bfc0|{>(da(YHFyk) zlzfHo>j-k@#D`s7U7NX03-Fl}ubFLHc+Z?TV76(&J#*qQvrQX?GbbJ}+qCeWIkClT z(}H{E#1G9jEwpD&Txqsxfjx7g+HBLpdgjChW}6n&GbhT-HZ7!QPL!B!+K`+%(cf&- zf_mmes?mnE?>CaQGZeNL?a49iaWU<}nD*e9cHfw`C#Ibg)7E0z|HS10t3F@Fv_Fe! zACGCjAJcx*+AjHQcKd6W``SP9wH-TMxu~L3yJHeUp))C;i^)X;6{XAbE0BD-+1EMw zLsWd7+8?QycrNHc=-fnggpRZ8XiEMDcvE>+mcW0E@yGo)6~n&qwV(DK_YFX%1=*xCgryMOP;j?JIc>lIyy8P zc*3?&zOU2s1{m!n^I+C5P!FqvNg3@=4JbOa-%|n9bbxOp@a!T6{}%n5qnPfHn8fs2 z3)72;>XAWA)h?KBL=i=c1BxkS2;qM`it#TH_;aH1+fI35au_Bb-AmW1_R(YwKmX6J zE?;~3IbYlQb4nxdg% z00v+fF4+&PU8o(RlRdFI)c%Z*`9sw%U;iUM=V4#_v)mK@6hr50Kj7;uN8cZP?XUXU z4~FLrL99Pfez@(lx@mt<>J|r1M|~ZkaIJ65Se6#l!u$RK^0w!EmszxPw-n(}Y4Zefrr^))0<1yB7 zZTV@Ricuhg=pRP&V0bjVhcQU8bd?}k``XG+t4z_hU-wNc54Y~w9AkGCB4c}OWVEf{ zt_0VCa69DeG6H1Rw*<(GG{Ug~G7|H{43N-B@I!c(Q{drWsT=h}Fljs5hkWgCksbfQ zu$_$CjL|_Sg^&nXgwWMrvy-YUAwrIuT!BR_q?SVJA*<8QVLBZw57RKAJWA!s z^Ij28u#1J7;y-?7ww&MS|R%CXuk4TSUWAOpZYc+b>kToCb|Y_l14r zlW-Hwa@oQ8?f5zJ4BX8wr_8Y!F@g9H@$e^NfNWLK5eOS$c(lFuJT(pY6<8nJd93gC z!b8Nk?YZJh%PxybKBQ@wlC7_OF-Z^mQhv$di7CY$=cEdGP&wj7GIA|Qdz>;Uo6f>W zFxw8D5#m%H3S2O)j+=}+@?I&5@ZozVKAEl$;1a0e!~Ngl z!*6&Rt|=LE}~Ve z#=$Cdiy0Dh%W7vOh4;A|j5a3En3N~9rdmZ2t0boznE(!kmm)8nOf$F-!ZZ}VjKrJo z;0uVqE-`ybfNt5Ih≦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 JBTwPB_#b) literal 0 HcmV?d00001 diff --git a/src/inlupp2/business_logic/backend.h b/demo/business_logic/backend.h similarity index 99% rename from src/inlupp2/business_logic/backend.h rename to demo/business_logic/backend.h index 1a84a2d..95336f8 100644 --- a/src/inlupp2/business_logic/backend.h +++ b/demo/business_logic/backend.h @@ -8,7 +8,7 @@ #include "../generic_data_structures/hash_table.h" #include "../generic_data_structures/iterator.h" #include "../generic_utils/utils.h" -#include "../../ref.h" +#include "../../src/ref.h" /** diff --git a/src/inlupp2/business_logic/cart.c b/demo/business_logic/cart.c similarity index 99% rename from src/inlupp2/business_logic/cart.c rename to demo/business_logic/cart.c index 0c5c41b..c62864a 100644 --- a/src/inlupp2/business_logic/cart.c +++ b/demo/business_logic/cart.c @@ -10,7 +10,7 @@ #include "../generic_data_structures/hash_table.h" #include "../generic_data_structures/iterator.h" #include "../generic_utils/utils.h" -#include "../../ref.h" +#include "../../src/ref.h" #define Successful(o) (o.success == true) #define Unsuccessful(o) (o.success == false) diff --git a/src/inlupp2/business_logic/common.c b/demo/business_logic/common.c similarity index 98% rename from src/inlupp2/business_logic/common.c rename to demo/business_logic/common.c index 01f4918..03330dd 100644 --- a/src/inlupp2/business_logic/common.c +++ b/demo/business_logic/common.c @@ -10,7 +10,7 @@ #include "../generic_data_structures/hash_table.h" #include "../generic_data_structures/iterator.h" #include "../generic_utils/utils.h" -#include "../../ref.h" +#include "../../src/ref.h" bool pointer_is_null(void *ptr) { diff --git a/src/inlupp2/business_logic/common.h b/demo/business_logic/common.h similarity index 100% rename from src/inlupp2/business_logic/common.h rename to demo/business_logic/common.h diff --git a/src/inlupp2/business_logic/merch.c b/demo/business_logic/merch.c similarity index 99% rename from src/inlupp2/business_logic/merch.c rename to demo/business_logic/merch.c index 2437abd..1166e12 100644 --- a/src/inlupp2/business_logic/merch.c +++ b/demo/business_logic/merch.c @@ -10,8 +10,7 @@ #include "../generic_data_structures/hash_table.h" #include "../generic_data_structures/iterator.h" #include "../generic_utils/utils.h" -#include "../../ref.h" - +#include "../../src/ref.h" diff --git a/src/inlupp2/business_logic/shop.c b/demo/business_logic/shop.c similarity index 97% rename from src/inlupp2/business_logic/shop.c rename to demo/business_logic/shop.c index 4d626b4..661cda5 100644 --- a/src/inlupp2/business_logic/shop.c +++ b/demo/business_logic/shop.c @@ -10,7 +10,7 @@ #include "../generic_data_structures/hash_table.h" #include "../generic_data_structures/iterator.h" #include "../generic_utils/utils.h" -#include "../../ref.h" +#include "../../src/ref.h" void shop_destructor(obj *shop) { if (!shop) return; diff --git a/src/inlupp2/coverage.txt b/demo/coverage.txt similarity index 100% rename from src/inlupp2/coverage.txt rename to demo/coverage.txt diff --git a/demo/frontend b/demo/frontend new file mode 100644 index 0000000000000000000000000000000000000000..7f10bf1021aa2ff20bfe1afcd7748f7144d13ff1 GIT binary patch literal 121352 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

}>pO_*;a&ynj^ssQO~vcR+9^0H1S6PHScU}` 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 #oPb}DM#*ig_;DOP&nFi|2Qh=)R)RN_648@?t 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 jLj5y%LUQ^U)>DJOaQ #include #include "linked_list.h" -#include "../../ref.h" +#include "../../src/ref.h" #define Success(k, v) \ (ioopm_option_t) { .success = true, .key = k, .value = v } diff --git a/src/inlupp2/generic_data_structures/hash_table.h b/demo/generic_data_structures/hash_table.h similarity index 100% rename from src/inlupp2/generic_data_structures/hash_table.h rename to demo/generic_data_structures/hash_table.h diff --git a/src/inlupp2/generic_data_structures/hash_table_tests.c b/demo/generic_data_structures/hash_table_tests.c similarity index 100% rename from src/inlupp2/generic_data_structures/hash_table_tests.c rename to demo/generic_data_structures/hash_table_tests.c diff --git a/src/inlupp2/generic_data_structures/iterator.h b/demo/generic_data_structures/iterator.h similarity index 100% rename from src/inlupp2/generic_data_structures/iterator.h rename to demo/generic_data_structures/iterator.h diff --git a/src/inlupp2/generic_data_structures/linked_list.c b/demo/generic_data_structures/linked_list.c similarity index 99% rename from src/inlupp2/generic_data_structures/linked_list.c rename to demo/generic_data_structures/linked_list.c index 5faf5b4..212793d 100644 --- a/src/inlupp2/generic_data_structures/linked_list.c +++ b/demo/generic_data_structures/linked_list.c @@ -4,7 +4,7 @@ #include #include "common.h" #include -#include "../../ref.h" +#include "../../src/ref.h" #define null_elem \ (elem_t) { 0 } diff --git a/src/inlupp2/generic_data_structures/linked_list.h b/demo/generic_data_structures/linked_list.h similarity index 100% rename from src/inlupp2/generic_data_structures/linked_list.h rename to demo/generic_data_structures/linked_list.h diff --git a/src/inlupp2/generic_data_structures/linked_list_tests.c b/demo/generic_data_structures/linked_list_tests.c similarity index 100% rename from src/inlupp2/generic_data_structures/linked_list_tests.c rename to demo/generic_data_structures/linked_list_tests.c diff --git a/src/inlupp2/generic_utils/utils.c b/demo/generic_utils/utils.c similarity index 98% rename from src/inlupp2/generic_utils/utils.c rename to demo/generic_utils/utils.c index 6e6b424..63ded81 100644 --- a/src/inlupp2/generic_utils/utils.c +++ b/demo/generic_utils/utils.c @@ -4,7 +4,7 @@ extern char *strdup(const char *); #include //för isdigit #include #include "utils.h" -#include "../../ref.h" +#include "../../src/ref.h" bool not_empty(char *str) { diff --git a/src/inlupp2/generic_utils/utils.h b/demo/generic_utils/utils.h similarity index 100% rename from src/inlupp2/generic_utils/utils.h rename to demo/generic_utils/utils.h diff --git a/src/inlupp2/makefile b/demo/makefile similarity index 89% rename from src/inlupp2/makefile rename to demo/makefile index 8b94310..2db8550 100644 --- a/src/inlupp2/makefile +++ b/demo/makefile @@ -2,21 +2,22 @@ clean: rm -f *.o frontend backend_tests old_hash old_list *.gcno *.gcda *.gcov backend_tests_coverage frontend: user_interface/frontend.c generic_utils/utils.c generic_data_structures/linked_list.c generic_data_structures/hash_table.c business_logic/shop.c business_logic/merch.c business_logic/cart.c business_logic/common.c - gcc -g -Wall -pedantic user_interface/frontend.c generic_utils/utils.c generic_data_structures/linked_list.c generic_data_structures/hash_table.c business_logic/shop.c business_logic/merch.c business_logic/cart.c business_logic/common.c ../ref.c ../lib/lib_hash_table.c ../lib/lib_linked_list.c -o frontend + gcc -g user_interface/frontend.c generic_utils/utils.c generic_data_structures/linked_list.c generic_data_structures/hash_table.c business_logic/shop.c business_logic/merch.c business_logic/cart.c business_logic/common.c ../src/ref.c ../src/lib/lib_hash_table.c ../src/lib/lib_linked_list.c -o frontend -w run_frontend: - ./frontend + clear; ./frontend val_frontend: valgrind -s ./frontend full_val_frontend: - valgrind -s --leak-check=full ./frontend + make frontend; clear; valgrind -s --leak-check=full ./frontend clean_frontend: make clean; make frontend; make run_frontend start: + clear make clean_frontend clean_val_frontend: diff --git a/src/inlupp2/readme.md b/demo/readme.md similarity index 100% rename from src/inlupp2/readme.md rename to demo/readme.md diff --git a/src/inlupp2/tests/backend_tests.c b/demo/tests/backend_tests.c similarity index 99% rename from src/inlupp2/tests/backend_tests.c rename to demo/tests/backend_tests.c index 4a71924..7444870 100644 --- a/src/inlupp2/tests/backend_tests.c +++ b/demo/tests/backend_tests.c @@ -7,7 +7,7 @@ #include "../generic_data_structures/linked_list.h" #include "../generic_data_structures/hash_table.h" #include "../generic_data_structures/iterator.h" -#include "../../ref.h" +#include "../../src/ref.h" typedef struct merch ioopm_merch_t; typedef struct shelf ioopm_shelf_t; @@ -15,7 +15,6 @@ typedef struct shop ioopm_shop_t; typedef struct shopping_carts shopping_carts_t; typedef struct cart cart_t; typedef struct cart_item cart_item_t; - #define Successful(o) (o.success == true) #define Unsuccessful(o) (o.success == false) diff --git a/src/inlupp2/user_interface/frontend.c b/demo/user_interface/frontend.c similarity index 99% rename from src/inlupp2/user_interface/frontend.c rename to demo/user_interface/frontend.c index aff1cda..4108168 100644 --- a/src/inlupp2/user_interface/frontend.c +++ b/demo/user_interface/frontend.c @@ -9,7 +9,7 @@ #include "../generic_data_structures/hash_table.h" #include "../generic_data_structures/iterator.h" #include "../generic_utils/utils.h" -#include "../../ref.h" +#include "../../src/ref.h" #define ValidOptions "AaLlDdEeSsPpCcRr+-=OoQq" diff --git a/src/inlupp2/user_interface/ui-tests/addMerch.txt b/demo/user_interface/ui-tests/addMerch.txt similarity index 100% rename from src/inlupp2/user_interface/ui-tests/addMerch.txt rename to demo/user_interface/ui-tests/addMerch.txt diff --git a/src/inlupp2/user_interface/ui-tests/addMultipleMerch.txt b/demo/user_interface/ui-tests/addMultipleMerch.txt similarity index 100% rename from src/inlupp2/user_interface/ui-tests/addMultipleMerch.txt rename to demo/user_interface/ui-tests/addMultipleMerch.txt diff --git a/src/inlupp2/user_interface/ui-tests/createCart.txt b/demo/user_interface/ui-tests/createCart.txt similarity index 100% rename from src/inlupp2/user_interface/ui-tests/createCart.txt rename to demo/user_interface/ui-tests/createCart.txt diff --git a/src/inlupp2/user_interface/ui-tests/editMerchInShelf.txt b/demo/user_interface/ui-tests/editMerchInShelf.txt similarity index 100% rename from src/inlupp2/user_interface/ui-tests/editMerchInShelf.txt rename to demo/user_interface/ui-tests/editMerchInShelf.txt diff --git a/src/inlupp2/user_interface/ui-tests/editOneMerch.txt b/demo/user_interface/ui-tests/editOneMerch.txt similarity index 100% rename from src/inlupp2/user_interface/ui-tests/editOneMerch.txt rename to demo/user_interface/ui-tests/editOneMerch.txt diff --git a/src/inlupp2/user_interface/ui-tests/editOneMerchInStock.txt b/demo/user_interface/ui-tests/editOneMerchInStock.txt similarity index 100% rename from src/inlupp2/user_interface/ui-tests/editOneMerchInStock.txt rename to demo/user_interface/ui-tests/editOneMerchInStock.txt diff --git a/src/inlupp2/user_interface/ui-tests/listMerchPaging.txt b/demo/user_interface/ui-tests/listMerchPaging.txt similarity index 100% rename from src/inlupp2/user_interface/ui-tests/listMerchPaging.txt rename to demo/user_interface/ui-tests/listMerchPaging.txt diff --git a/src/inlupp2/user_interface/ui-tests/quitWithMerchInCart.txt b/demo/user_interface/ui-tests/quitWithMerchInCart.txt similarity index 100% rename from src/inlupp2/user_interface/ui-tests/quitWithMerchInCart.txt rename to demo/user_interface/ui-tests/quitWithMerchInCart.txt diff --git a/src/inlupp2/user_interface/ui-tests/removeCartWithMerch.txt b/demo/user_interface/ui-tests/removeCartWithMerch.txt similarity index 100% rename from src/inlupp2/user_interface/ui-tests/removeCartWithMerch.txt rename to demo/user_interface/ui-tests/removeCartWithMerch.txt diff --git a/src/inlupp2/user_interface/ui-tests/removeMany.txt b/demo/user_interface/ui-tests/removeMany.txt similarity index 100% rename from src/inlupp2/user_interface/ui-tests/removeMany.txt rename to demo/user_interface/ui-tests/removeMany.txt diff --git a/src/inlupp2/user_interface/ui-tests/removeOne.txt b/demo/user_interface/ui-tests/removeOne.txt similarity index 100% rename from src/inlupp2/user_interface/ui-tests/removeOne.txt rename to demo/user_interface/ui-tests/removeOne.txt diff --git a/src/inlupp2/user_interface/ui-tests/replenishMerch.txt b/demo/user_interface/ui-tests/replenishMerch.txt similarity index 100% rename from src/inlupp2/user_interface/ui-tests/replenishMerch.txt rename to demo/user_interface/ui-tests/replenishMerch.txt diff --git a/src/inlupp2/user_interface/ui-tests/replenishMerchAdv.txt b/demo/user_interface/ui-tests/replenishMerchAdv.txt similarity index 100% rename from src/inlupp2/user_interface/ui-tests/replenishMerchAdv.txt rename to demo/user_interface/ui-tests/replenishMerchAdv.txt diff --git a/proj/design_report.md b/proj/design_report.md deleted file mode 100644 index 9ae7b33..0000000 --- a/proj/design_report.md +++ /dev/null @@ -1,47 +0,0 @@ -# Design Documentation -This is a memory management library that implements a basic version of reference counting. -It is designed to replace malloc/calloc and free in a program with library functions like -allocate/release. This would make memory management safer avoiding memory leaks. The library -also supports limiting cascading frees. - -# High level Design - -Metadata management: -For each allocated object a metadata struct is stored in a hash table. The struct includes: -- Reference count (rc): Tracks number of active references -- Destructor function pointer: To allow custom destructors for common complex data structures -- Object size in bytes: Used for memory release and validation - -Reference counting: -- Functions retain and release modify the reference count (rc) -- Objects are deallocated when the rc is 0 -- The release function schedules objects for destruction - -Scheduling: -- Objects with rc = 0 are scheduled for destruction using a linked list -- Scheduled objects are processed using free_scheduled_tasks, which frees a set number of - objects per call, as defined by a global cascade limit - -Destructors: -- Default destructor is implemented that can free complex data structures. It manages recursive - destruction of pointer-based objects. -- Custom destructors for hash-tables and linked-lists are made which improve performance for - those data structures - -Memory allocation: -- Objects are allocated using allocate or allocate_array -- A metadata_t struct is associated with each allocated object, storing size and destructor. - -Cleanup: -- Cleanup clears out all objects scheduled for deallocation. - -Shutdown: -- Cleans up all system resources. Frees all objects and destroys hash table and linked list - used in library functions - -# User implementation -For this library to work with any program, one would need to do the following: - -1) Replace malloc/calloc with allocate (or allocate_array) -2) Replace free with release -3) Call shutdown() when program ends. diff --git a/test/test.c b/test/test.c index 6f16d8d..c2f9084 100644 --- a/test/test.c +++ b/test/test.c @@ -4,27 +4,24 @@ #include #include #include "../src/lib/lib_linked_list.h" -#include "../src/inlupp2/generic_data_structures/linked_list.h" #include #include -struct cell -{ +struct cell { struct cell *cell; int i; char *string; }; + typedef struct lib_link lib_link_t; -struct lib_link -{ +struct lib_link { lib_elem_t value; lib_link_t *previous; lib_link_t *next; }; -void cell_destructor(obj *c) //kanske borde returna Size på det vi tagit bort? -{ +void cell_destructor(obj *c) { //kanske borde returna Size på det vi tagit bort? release(((struct cell *) c)->cell); } @@ -45,8 +42,7 @@ int clean_suite(void) { // Unit tests -void test_allocate_and_deallocate(void) -{ +void test_allocate_and_deallocate(void) { // Set cascade limit set_cascade_limit(1); @@ -161,8 +157,7 @@ void test_default_destructor() { (lib_elem_t) { 0 } // Helper function for testing on links -static lib_link_t *link_create_with_allocate(lib_elem_t value, lib_link_t *previous, lib_link_t *next) -{ +static lib_link_t *link_create_with_allocate(lib_elem_t value, lib_link_t *previous, lib_link_t *next) { lib_link_t *link = allocate(sizeof(lib_link_t), NULL); link->previous = previous; link->next = next; @@ -172,8 +167,7 @@ static lib_link_t *link_create_with_allocate(lib_elem_t value, lib_link_t *previ } -void test_allocate_and_deallocate_links(void) -{ +void test_allocate_and_deallocate_links(void) { // Set cascade limit set_cascade_limit(1); @@ -193,8 +187,7 @@ void test_allocate_and_deallocate_links(void) deallocate(link3); } -void test_allocate_array_then_deallocate(void) -{ +void test_allocate_array_then_deallocate(void) { // Set cascade limit set_cascade_limit(3); @@ -216,8 +209,7 @@ void test_allocate_array_then_deallocate(void) //should not leak when running tests! } -void test_allocate_strings_then_release(void) -{ +void test_allocate_strings_then_release(void) { // Set cascade limit set_cascade_limit(1); @@ -252,7 +244,7 @@ void test_allocate_strings_then_release(void) // free_all(); } -void test_get_and_set_cascade_limit(){ +void test_get_and_set_cascade_limit() { // Set cascade limit set_cascade_limit(2); // Check that get_cascade_limit gets the right limit @@ -269,6 +261,7 @@ void test_get_and_set_cascade_limit(){ // Binary trees typedef struct node node_t; + struct node { int val; node_t *left; @@ -536,4 +529,4 @@ int main() { // Tear down CUnit before exiting CU_cleanup_registry(); return CU_get_error(); -} \ No newline at end of file +} \ No newline at end of file From 8a56022b6230533d9c2b990ae36b0a7c59569742 Mon Sep 17 00:00:00 2001 From: Truxilla <149168007+Truxilla@users.noreply.github.com> Date: Mon, 13 Jan 2025 22:01:41 +0100 Subject: [PATCH 2/4] changed ref.c and ref.h to refmem.c and refmem.h --- demo/business_logic/backend.h | 2 +- demo/business_logic/cart.c | 2 +- demo/business_logic/common.c | 2 +- demo/business_logic/merch.c | 2 +- demo/business_logic/shop.c | 2 +- demo/frontend | Bin 121352 -> 121376 bytes demo/generic_data_structures/hash_table.c | 2 +- demo/generic_data_structures/linked_list.c | 2 +- demo/generic_utils/utils.c | 2 +- demo/makefile | 12 +- demo/tests/backend_tests.c | 2 +- demo/user_interface/frontend.c | 2 +- src/{ref.c => refmem.c} | 486 ++++++++++----------- src/{ref.h => refmem.h} | 266 +++++------ test/test.c | 2 +- 15 files changed, 393 insertions(+), 393 deletions(-) rename src/{ref.c => refmem.c} (96%) rename src/{ref.h => refmem.h} (96%) diff --git a/demo/business_logic/backend.h b/demo/business_logic/backend.h index 95336f8..8caaf15 100644 --- a/demo/business_logic/backend.h +++ b/demo/business_logic/backend.h @@ -8,7 +8,7 @@ #include "../generic_data_structures/hash_table.h" #include "../generic_data_structures/iterator.h" #include "../generic_utils/utils.h" -#include "../../src/ref.h" +#include "../../src/refmem.h" /** diff --git a/demo/business_logic/cart.c b/demo/business_logic/cart.c index c62864a..71eff69 100644 --- a/demo/business_logic/cart.c +++ b/demo/business_logic/cart.c @@ -10,7 +10,7 @@ #include "../generic_data_structures/hash_table.h" #include "../generic_data_structures/iterator.h" #include "../generic_utils/utils.h" -#include "../../src/ref.h" +#include "../../src/refmem.h" #define Successful(o) (o.success == true) #define Unsuccessful(o) (o.success == false) diff --git a/demo/business_logic/common.c b/demo/business_logic/common.c index 03330dd..6ee3659 100644 --- a/demo/business_logic/common.c +++ b/demo/business_logic/common.c @@ -10,7 +10,7 @@ #include "../generic_data_structures/hash_table.h" #include "../generic_data_structures/iterator.h" #include "../generic_utils/utils.h" -#include "../../src/ref.h" +#include "../../src/refmem.h" bool pointer_is_null(void *ptr) { diff --git a/demo/business_logic/merch.c b/demo/business_logic/merch.c index 1166e12..41f4257 100644 --- a/demo/business_logic/merch.c +++ b/demo/business_logic/merch.c @@ -10,7 +10,7 @@ #include "../generic_data_structures/hash_table.h" #include "../generic_data_structures/iterator.h" #include "../generic_utils/utils.h" -#include "../../src/ref.h" +#include "../../src/refmem.h" diff --git a/demo/business_logic/shop.c b/demo/business_logic/shop.c index 661cda5..14d29bf 100644 --- a/demo/business_logic/shop.c +++ b/demo/business_logic/shop.c @@ -10,7 +10,7 @@ #include "../generic_data_structures/hash_table.h" #include "../generic_data_structures/iterator.h" #include "../generic_utils/utils.h" -#include "../../src/ref.h" +#include "../../src/refmem.h" void shop_destructor(obj *shop) { if (!shop) return; diff --git a/demo/frontend b/demo/frontend index 7f10bf1021aa2ff20bfe1afcd7748f7144d13ff1..767216bfa46f75982b1e0b9447f2d49706730229 100644 GIT binary patch delta 6602 zcmb`Mdt8)d_Q2mW!!R?-ZHDV`9YAi%RZ&4LBy+VbL(;TRH_24g4;rG9Hw==>w3TVh zLz)JAe^)(HzYsm09RernV(#7g?ef!(i7$=oMYTLVulG2Uk zbIaW~Fs#keusy^7K&Yl!d_!g!H7&T--STz?6t^Xut~XNC_ReU4V)u=A?||C2j6XJ8 zbY+8YNWP|N##;B~4}S+|-22XrC8aOUjexh@ap(8=M@MQJ1cs&>G;LtByYqZ9M7zH` ze~NUDew0t|n;(s*_vi}+^j>{o3cb%>m_zSjACIGV6~Eh#e%xcCk3E0Mgj)Bxzqo>; z9pp6U?pfs2;F=iS>|XxYQ}+A-`r`QeLu$LHD*y&phiKXnfEdfmplJb12asu;e-)W( zfoBMT({BKQ1_&JKuIU~DJ(!gOaqbJ%o%dYI9cfi#H^zOJ?Pw#s__kgv{__u8aGT7Nu1kr6@^$Z0V>5jj4%J4J0yYan^ z?#HhuKy{n@`XQqsFN7rldhkBJA*U!bOD#46RM?9nXgpiYnr5;_kEbvPzU6+TcbJ{W zWO%?&(|kk2pJQ>4r_2Cd#Uq+=Yx?RA0^M76dhh953&k%cLJ{=5SP3r}QltKV0$gW;O3xQ&=r-6Z zIrW*acmhuz*VolyJ^1MWI10sx17WvK$Db}x^!@7C9?!jgKtn9X_5j!h#h#)-h@dfG zSrEKJjl~APBq`b;5DZu1Dco8d91J#nj#5tFp>C|To{7OQ#smwoE&_Hrh6U4npxT~z zj37OeXln2?1jjmH64>#V4!AEVgl3daMDPj%hJ58rl_Kh?;gKMnQSG>~hqCa7}v%{h6 z%;-9@jvW0FuaF~~?r8T9jt*mjld|1_4r|xj8?$F?xtU5*+#Y0-cT{t5i(w%xTpBbr=DOwx)$C^-!`{E&H zwyw1@nYB3Tu+u!sRnqfAVT<^4wR}!?ZdjlOJ4!WLSShD?T>zKd;3^8sqrt$!VEl{ z05Na~|DFK%JIWc)2pU0)h?B;%vx(k`p*S@Wa^m&QrbuTrQoWv2y`5=s58>WKNT)^c zVImZ$h{yJ)EAcm&ILPZH{|6^;a-XC6orD+R@Z;3)y**eT=G?F~3yW5v{mA6=Id#^aGpsG@OX zXVLi+jZbF5B1ppPS@0126~|{&Hb-JzHq07)nQj5Re}}H5cHnt)emPQv zB=>}KKSNIrIN%I+=0L80JDspT7DoY>VG`PhQpR~7_pv%xkZ9luy2Zp!9Rtv{xwQzt|%T;;@{hWe^ z!{B>sJ$=y=ry81hE>gAec~3Z-KX@5gEyE}Z`&C>xj5e)ee0~@tPd>{&n!vY0d?fe# zu+hCu`DlVnuaBU7cKS5A5hLiqfFIj^=_B-o{Jx zrQb&2UdZu!wts^`!(phBkAq0BJg5$*4u?mABe>%X2;pq#n?leZ@bqw44%>0e2$%y2 z*f;`;!3Vz?0Z+jrxMC!f!!5ir5^~@<49lZwbOg8LK{tGgEApWM4r1UaD1pVea1_Nc z4G)hZ_dD^*D2liklSV_Py_VN+VTde#O^c|+xufApr(T$(sVbC-kq9;|1E%jd%y^L5>uOQEhZ*rl7*E`XUP^AVlZGwZ=WErCXzEq)x*Oy+TvFr!xM zA+{QHcaADJW&T(XU=Cicf&;p=a|y)Y{wJVBxAj>Glj8z2GqWm}&dFLjcOHe2Ima`l z0Rjx3#oHj!7Zs4+|N`(v)TAfeV%V5y81w!FZD3?s6r+Tkte&+DF^Ud^Pm!W*YiREN!Ns zpFvkM88(n1XyMxI_ryY)COpZwoiP1Qq=hv682=u78Bh1;sAvNU`Z4}9#=lDV23gyQ z)z>L(60JTgW*kU$WxO?C$p;Be!y3k;1m`6wx%WIO##Y8l1V7||UbIDs~3erTK3p9+Kn5N_H)*y(OH1Vbg}kifA=^ov$2J#T2ov6S%#f_KUUnkeqh zql@vsyw~#9KmhzO70On8smRWc#`0*HA-GgdjLO= zDO@FZsoahO71cIj4O{<8aE#>dS-~CH%J>7p^`%N)BF?X2H)GALBCiqW8^wA6+71%7 z34Tc;_g;~su#oXk!6*5*7NF*nQfdFjCc?BQ<{YACBX+X#c2U0m zpi(|AzM2t8%h4)$q&TS*{CnMr<1@kTS|#rh{4JKUwV5^-E>PZMN`8mnaC8wi4Q8y* zmOJqz>pv*^H=~-$Qv{F0ZpNj8v+|VueyQ+Ew6zf4EO>p9!f())$j`S} z$hb-HH@Qmey+d?h1>-Y<*Cr~=M}GsitedkG@b=b;wl>0F3cf2vVQ+zau#j;mofDkYFIOo%SG=cV z1>*^V_s9^v+vH4aV!TLjvxF>8v>NPW+#s0mJN)cYjdlQ`op8HgryK(^0PO_kFzyuG zJ4%`D6zd)=W&97pE5uA@w>A)6jGc4}^1xCA7m0N)o@6{pu(M9dz2lyRy^JdbUzQ!K zPG&?k#=lP3Ex1J@_fEx|Sj_lk!H2|aiS&I4YZ#YGNxEW{{Gj09VXN-k$VYdimiLo- zcVRc=HE!2z<+V?oM`9u4!GgWNs6+`KhZT$;6r3qrlJ|yD zhE0s05S$~^LC#h>OF9|b>Bhl1|E<(}kYw!@1P|c@Vtq|!(Ff9Z3+6CBEjX`6$z}Cu zm#~!aKLx)gxKONp(Zx72Q1xAKzml&NoP{SD7YLp&fBWeWJP~^t7YY99Ux=n-{1L*B z3-3hxl>E^KAoD|oG7NuFlLZpMj{)XlQ3 zdrOjswl@e5k?F8_q4MgTOh3m$#mNFhGc!ea@ zdq@_ci}75+iNVV2Gva(Ho@Bg9@D7RmQNaz^%eY1G)5%JHOz;_uKT7zb;Fb&}_ZF1a zH{&3?ihRHH?M(~akr|H{{4ZG^+r;_9*vfdm;MDt+Jlvq#b=b{#i{K>bd!tw%MB6dK zrv)FAdG6hj&tf5A=<+;#3^o}|`tMuV{St(FzNh~Z*gcj`Xf)HE>D7;6q%~jmvqbEn hPne1EpU@vA>amm>>$Atyvi%xg{e&Q0-9Lep{{mBp@8kdg delta 6614 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 diff --git a/demo/generic_data_structures/hash_table.c b/demo/generic_data_structures/hash_table.c index 32e5695..b0317a7 100644 --- a/demo/generic_data_structures/hash_table.c +++ b/demo/generic_data_structures/hash_table.c @@ -5,7 +5,7 @@ #include #include #include "linked_list.h" -#include "../../src/ref.h" +#include "../../src/refmem.h" #define Success(k, v) \ (ioopm_option_t) { .success = true, .key = k, .value = v } diff --git a/demo/generic_data_structures/linked_list.c b/demo/generic_data_structures/linked_list.c index 212793d..6d66fe9 100644 --- a/demo/generic_data_structures/linked_list.c +++ b/demo/generic_data_structures/linked_list.c @@ -4,7 +4,7 @@ #include #include "common.h" #include -#include "../../src/ref.h" +#include "../../src/refmem.h" #define null_elem \ (elem_t) { 0 } diff --git a/demo/generic_utils/utils.c b/demo/generic_utils/utils.c index 63ded81..c74df12 100644 --- a/demo/generic_utils/utils.c +++ b/demo/generic_utils/utils.c @@ -4,7 +4,7 @@ extern char *strdup(const char *); #include //för isdigit #include #include "utils.h" -#include "../../src/ref.h" +#include "../../src/refmem.h" bool not_empty(char *str) { diff --git a/demo/makefile b/demo/makefile index 2db8550..66ee0af 100644 --- a/demo/makefile +++ b/demo/makefile @@ -2,7 +2,7 @@ clean: rm -f *.o frontend backend_tests old_hash old_list *.gcno *.gcda *.gcov backend_tests_coverage frontend: user_interface/frontend.c generic_utils/utils.c generic_data_structures/linked_list.c generic_data_structures/hash_table.c business_logic/shop.c business_logic/merch.c business_logic/cart.c business_logic/common.c - gcc -g user_interface/frontend.c generic_utils/utils.c generic_data_structures/linked_list.c generic_data_structures/hash_table.c business_logic/shop.c business_logic/merch.c business_logic/cart.c business_logic/common.c ../src/ref.c ../src/lib/lib_hash_table.c ../src/lib/lib_linked_list.c -o frontend -w + gcc -g user_interface/frontend.c generic_utils/utils.c generic_data_structures/linked_list.c generic_data_structures/hash_table.c business_logic/shop.c business_logic/merch.c business_logic/cart.c business_logic/common.c ../src/refmem.c ../src/lib/lib_hash_table.c ../src/lib/lib_linked_list.c -o frontend -w run_frontend: clear; ./frontend @@ -26,8 +26,8 @@ clean_val_frontend: clean_full_val_frontend: make clean; make frontend; make full_val_frontend -backend_tests: business_logic/common.c business_logic/shop.c business_logic/merch.c business_logic/cart.c tests/backend_tests.c generic_utils/utils.c generic_data_structures/linked_list.c generic_data_structures/hash_table.c ../ref.c - gcc -g -Wall -pedantic business_logic/common.c business_logic/shop.c business_logic/merch.c business_logic/cart.c tests/backend_tests.c generic_utils/utils.c generic_data_structures/linked_list.c generic_data_structures/hash_table.c ../ref.c ../lib/lib_hash_table.c ../lib/lib_linked_list.c -lcunit -o backend_tests +backend_tests: business_logic/common.c business_logic/shop.c business_logic/merch.c business_logic/cart.c tests/backend_tests.c generic_utils/utils.c generic_data_structures/linked_list.c generic_data_structures/hash_table.c ../refmem.c + gcc -g -Wall -pedantic business_logic/common.c business_logic/shop.c business_logic/merch.c business_logic/cart.c tests/backend_tests.c generic_utils/utils.c generic_data_structures/linked_list.c generic_data_structures/hash_table.c ../refmem.c ../lib/lib_hash_table.c ../lib/lib_linked_list.c -lcunit -o backend_tests run_backend_tests: ./backend_tests @@ -57,15 +57,15 @@ gcov: gcov -b -c backend_tests_coverage-backend_tests.gcda > coverage.txt old_hash: - gcc -g -Wall -pedantic generic_data_structures/hash_table.c generic_data_structures/linked_list.c generic_data_structures/hash_table_tests.c ../ref.c ../lib/lib_hash_table.c ../lib/lib_linked_list.c -lcunit -o old_hash + gcc -g -Wall -pedantic generic_data_structures/hash_table.c generic_data_structures/linked_list.c generic_data_structures/hash_table_tests.c ../refmem.c ../lib/lib_hash_table.c ../lib/lib_linked_list.c -lcunit -o old_hash valgrind -s --leak-check=full ./old_hash old_list: - gcc -g -Wall -pedantic generic_data_structures/linked_list.c generic_data_structures/linked_list_tests.c ../ref.c ../lib/lib_hash_table.c ../lib/lib_linked_list.c -lcunit -o old_list + gcc -g -Wall -pedantic generic_data_structures/linked_list.c generic_data_structures/linked_list_tests.c ../refmem.c ../lib/lib_hash_table.c ../lib/lib_linked_list.c -lcunit -o old_list valgrind -s --leak-check=full ./old_list old_list_full: - gcc -g -Wall -pedantic generic_data_structures/linked_list.c generic_data_structures/linked_list_tests.c ../ref.c ../lib/lib_hash_table.c ../lib/lib_linked_list.c -lcunit -o old_list + gcc -g -Wall -pedantic generic_data_structures/linked_list.c generic_data_structures/linked_list_tests.c ../refmem.c ../lib/lib_hash_table.c ../lib/lib_linked_list.c -lcunit -o old_list valgrind -s --leak-check=full --show-leak-kinds=all ./old_list tests_hidden: frontend diff --git a/demo/tests/backend_tests.c b/demo/tests/backend_tests.c index 7444870..3aa9fa6 100644 --- a/demo/tests/backend_tests.c +++ b/demo/tests/backend_tests.c @@ -7,7 +7,7 @@ #include "../generic_data_structures/linked_list.h" #include "../generic_data_structures/hash_table.h" #include "../generic_data_structures/iterator.h" -#include "../../src/ref.h" +#include "../../src/refmem.h" typedef struct merch ioopm_merch_t; typedef struct shelf ioopm_shelf_t; diff --git a/demo/user_interface/frontend.c b/demo/user_interface/frontend.c index 4108168..0748fca 100644 --- a/demo/user_interface/frontend.c +++ b/demo/user_interface/frontend.c @@ -9,7 +9,7 @@ #include "../generic_data_structures/hash_table.h" #include "../generic_data_structures/iterator.h" #include "../generic_utils/utils.h" -#include "../../src/ref.h" +#include "../../src/refmem.h" #define ValidOptions "AaLlDdEeSsPpCcRr+-=OoQq" diff --git a/src/ref.c b/src/refmem.c similarity index 96% rename from src/ref.c rename to src/refmem.c index cf585f2..bc8c596 100644 --- a/src/ref.c +++ b/src/refmem.c @@ -1,243 +1,243 @@ -#include "ref.h" -#include -#include -#include -#include -#include -#include -#include - -static lib_list_t *schedule_linked_list = NULL; -static lib_hash_table_t *metadata_ht = NULL; -static bool release_in_progress = false; -static const size_t STANDARD_CASCADE_LIMIT = 100; -static size_t CASCADE_LIMIT = 100; - -bool int_equal(lib_elem_t a, lib_elem_t b) { - return a.i == b.i; -} - -static int default_hash_function(lib_elem_t value) { - return value.i; -} - -static void initialize_collector() { - if (!metadata_ht) { - metadata_ht = lib_hash_table_create(int_equal, NULL, default_hash_function); - } - if (!schedule_linked_list) { - schedule_linked_list = lib_linked_list_create(int_equal); // TODO!!! int_equal, but ptr_elem values - } -} - -lib_hash_table_t *get_metadata_ht() { - if (metadata_ht == NULL) { - metadata_ht = lib_hash_table_create(int_equal, NULL, default_hash_function); - } - return metadata_ht; -} - -lib_list_t *get_schedule_linked_list() { - if (!schedule_linked_list) { - schedule_linked_list = lib_linked_list_create(int_equal); // TODO!!! int_equal, but ptr_elem values - } - return schedule_linked_list; -} - -metadata_t *metadata_generate(function1_t destructor, size_t size) { - metadata_t *metadata = calloc(1, sizeof(metadata_t)); - if (!metadata) return NULL; - metadata->rc = 0; - metadata->destructor = destructor; - metadata->size = size; - return metadata; -} - -static metadata_t *get_metadata(obj* object) { - uintptr_t key_as_int = (uintptr_t) object; - lib_option_t found_data = lib_hash_table_lookup(get_metadata_ht(), lib_int_elem(key_as_int)); - if(!found_data.success) return NULL; - return (metadata_t*) found_data.value.p; -} - -uint8_t rc(obj* object) { - metadata_t *metadata = get_metadata(object); - if (metadata) { - return metadata->rc; - } else { - printf("metadata could not be found!"); - return 0; - } -} - -void release_destructor(obj *to_remove) { - if (!to_remove) return; - metadata_t *metadata = get_metadata(to_remove); - if (metadata) { - metadata->destructor(to_remove); - } -} - -static bool is_valid_pointer(void *object){ - if (!object) return false; - uintptr_t key_as_int = (uintptr_t) object; - lib_option_t option = lib_hash_table_lookup(get_metadata_ht(), lib_int_elem(key_as_int)); - return option.success; -} - -static void destructor_loop(size_t object_size, obj *object) { - for (size_t offset = 0; offset + sizeof(void *) <= object_size; offset++) - { - void **possible_pointer = (void **)((char *)object + offset); - if (is_valid_pointer(*possible_pointer)) - { - release(*possible_pointer); - } - } -} - -static void default_destructor(obj* object) { - if(!object) return; - uintptr_t key_as_int = (uintptr_t) object; - lib_option_t option = lib_hash_table_lookup(get_metadata_ht(), lib_int_elem(key_as_int)); - if (!option.success) return; - metadata_t *metadata = (metadata_t *)(option.value.p); - size_t object_size = metadata->size; - destructor_loop(object_size, object); -} - -static void add_to_schedule(obj *object) { - metadata_t *metadata = get_metadata(object); - if(!metadata) return; - lib_linked_list_append(get_schedule_linked_list(), lib_ptr_elem(object)); - if (metadata->destructor) { - metadata->destructor(object); - } - else { - default_destructor(object); - } -} - -static void task_manager_loop(size_t size) { - size_t freed_size = 0; - size_t cascade_amount = 0; - while ((freed_size < size || cascade_amount < CASCADE_LIMIT) && - lib_linked_list_size(get_schedule_linked_list()) > 0) - { - bool successful1 = false; - obj *to_remove = lib_linked_list_get(get_schedule_linked_list(), 0, &successful1).p; - deallocate(to_remove); - cascade_amount++; - } - release_in_progress = false; -} - -static void schedule_task_manager(obj *object, size_t size) { - release_in_progress = true; - metadata_t *metadata = get_metadata(object); - if(object && metadata) { - if(metadata->rc == 0) { - add_to_schedule(object); - } - } - task_manager_loop(size); -} - -obj *allocate(size_t bytes, function1_t destructor) { - initialize_collector(); - schedule_task_manager(NULL, bytes); - obj *object = calloc(1, bytes); - uintptr_t key_as_int = (uintptr_t) object; - metadata_t *metadata = metadata_generate(destructor, bytes); - lib_hash_table_insert(get_metadata_ht(), lib_int_elem(key_as_int), lib_ptr_elem(metadata)); - return object; -} - -obj *allocate_array(size_t elements, size_t bytes, function1_t destructor) { - size_t total_size = elements * bytes; - return allocate(total_size, destructor); -} - -void deallocate(obj* object) { - if(!object) return; - uintptr_t key_as_int = (uintptr_t)object; - metadata_t *metadata = get_metadata(object); - if(!metadata) return; - assert(rc(object) == 0); - lib_list_option_t exist = lib_linked_list_contains(schedule_linked_list, lib_ptr_elem(object)); - if(exist.success) { - bool successful1 = false; - lib_linked_list_remove(schedule_linked_list, exist.value.i, &successful1); - } - lib_hash_table_remove(get_metadata_ht(), lib_int_elem(key_as_int)); - free(metadata); - free(object); -} - -void retain(obj *object) { - if (!object) return; - uintptr_t key_as_int = (uintptr_t)object; - lib_option_t option = lib_hash_table_lookup(get_metadata_ht(), lib_int_elem(key_as_int)); - if (option.success) { - metadata_t *metadata = (metadata_t *)(option.value.p); - metadata->rc++; - } -} - -void release(obj *object) { - if (!object) return; - metadata_t *metadata = get_metadata(object); - if (!metadata) return; - else if(metadata->rc > 0) { - metadata->rc--; - } - if(metadata->rc == 0) { - if(!release_in_progress){ - schedule_task_manager(object, 0); - } - else { - add_to_schedule(object); - } - } -} - -void cleanup() { - schedule_task_manager(NULL, SIZE_MAX); -} - -static void free_all() { - cleanup(); - lib_linked_list_destroy(get_schedule_linked_list()); - schedule_linked_list = NULL; - lib_hash_table_destroy(get_metadata_ht()); -} - -void shutdown() { - set_cascade_limit(STANDARD_CASCADE_LIMIT); - free_all(); -} - -size_t get_cascade_limit() { - return CASCADE_LIMIT; -} - -void set_cascade_limit(size_t size) { - CASCADE_LIMIT = size; -} - -void str_dummy_destructor(obj *o) { -} - -char *rc_strdup(char *src) { - char *str; - char *p; - int len = 0; - while (src[len]) len++; - str = allocate(len + 1, str_dummy_destructor); - p = str; - while (*src) - *p++ = *src++; - *p = '\0'; - return str; -} - +#include "refmem.h" +#include +#include +#include +#include +#include +#include +#include + +static lib_list_t *schedule_linked_list = NULL; +static lib_hash_table_t *metadata_ht = NULL; +static bool release_in_progress = false; +static const size_t STANDARD_CASCADE_LIMIT = 100; +static size_t CASCADE_LIMIT = 100; + +bool int_equal(lib_elem_t a, lib_elem_t b) { + return a.i == b.i; +} + +static int default_hash_function(lib_elem_t value) { + return value.i; +} + +static void initialize_collector() { + if (!metadata_ht) { + metadata_ht = lib_hash_table_create(int_equal, NULL, default_hash_function); + } + if (!schedule_linked_list) { + schedule_linked_list = lib_linked_list_create(int_equal); // TODO!!! int_equal, but ptr_elem values + } +} + +lib_hash_table_t *get_metadata_ht() { + if (metadata_ht == NULL) { + metadata_ht = lib_hash_table_create(int_equal, NULL, default_hash_function); + } + return metadata_ht; +} + +lib_list_t *get_schedule_linked_list() { + if (!schedule_linked_list) { + schedule_linked_list = lib_linked_list_create(int_equal); // TODO!!! int_equal, but ptr_elem values + } + return schedule_linked_list; +} + +metadata_t *metadata_generate(function1_t destructor, size_t size) { + metadata_t *metadata = calloc(1, sizeof(metadata_t)); + if (!metadata) return NULL; + metadata->rc = 0; + metadata->destructor = destructor; + metadata->size = size; + return metadata; +} + +static metadata_t *get_metadata(obj* object) { + uintptr_t key_as_int = (uintptr_t) object; + lib_option_t found_data = lib_hash_table_lookup(get_metadata_ht(), lib_int_elem(key_as_int)); + if(!found_data.success) return NULL; + return (metadata_t*) found_data.value.p; +} + +uint8_t rc(obj* object) { + metadata_t *metadata = get_metadata(object); + if (metadata) { + return metadata->rc; + } else { + printf("metadata could not be found!"); + return 0; + } +} + +void release_destructor(obj *to_remove) { + if (!to_remove) return; + metadata_t *metadata = get_metadata(to_remove); + if (metadata) { + metadata->destructor(to_remove); + } +} + +static bool is_valid_pointer(void *object){ + if (!object) return false; + uintptr_t key_as_int = (uintptr_t) object; + lib_option_t option = lib_hash_table_lookup(get_metadata_ht(), lib_int_elem(key_as_int)); + return option.success; +} + +static void destructor_loop(size_t object_size, obj *object) { + for (size_t offset = 0; offset + sizeof(void *) <= object_size; offset++) + { + void **possible_pointer = (void **)((char *)object + offset); + if (is_valid_pointer(*possible_pointer)) + { + release(*possible_pointer); + } + } +} + +static void default_destructor(obj* object) { + if(!object) return; + uintptr_t key_as_int = (uintptr_t) object; + lib_option_t option = lib_hash_table_lookup(get_metadata_ht(), lib_int_elem(key_as_int)); + if (!option.success) return; + metadata_t *metadata = (metadata_t *)(option.value.p); + size_t object_size = metadata->size; + destructor_loop(object_size, object); +} + +static void add_to_schedule(obj *object) { + metadata_t *metadata = get_metadata(object); + if(!metadata) return; + lib_linked_list_append(get_schedule_linked_list(), lib_ptr_elem(object)); + if (metadata->destructor) { + metadata->destructor(object); + } + else { + default_destructor(object); + } +} + +static void task_manager_loop(size_t size) { + size_t freed_size = 0; + size_t cascade_amount = 0; + while ((freed_size < size || cascade_amount < CASCADE_LIMIT) && + lib_linked_list_size(get_schedule_linked_list()) > 0) + { + bool successful1 = false; + obj *to_remove = lib_linked_list_get(get_schedule_linked_list(), 0, &successful1).p; + deallocate(to_remove); + cascade_amount++; + } + release_in_progress = false; +} + +static void schedule_task_manager(obj *object, size_t size) { + release_in_progress = true; + metadata_t *metadata = get_metadata(object); + if(object && metadata) { + if(metadata->rc == 0) { + add_to_schedule(object); + } + } + task_manager_loop(size); +} + +obj *allocate(size_t bytes, function1_t destructor) { + initialize_collector(); + schedule_task_manager(NULL, bytes); + obj *object = calloc(1, bytes); + uintptr_t key_as_int = (uintptr_t) object; + metadata_t *metadata = metadata_generate(destructor, bytes); + lib_hash_table_insert(get_metadata_ht(), lib_int_elem(key_as_int), lib_ptr_elem(metadata)); + return object; +} + +obj *allocate_array(size_t elements, size_t bytes, function1_t destructor) { + size_t total_size = elements * bytes; + return allocate(total_size, destructor); +} + +void deallocate(obj* object) { + if(!object) return; + uintptr_t key_as_int = (uintptr_t)object; + metadata_t *metadata = get_metadata(object); + if(!metadata) return; + assert(rc(object) == 0); + lib_list_option_t exist = lib_linked_list_contains(schedule_linked_list, lib_ptr_elem(object)); + if(exist.success) { + bool successful1 = false; + lib_linked_list_remove(schedule_linked_list, exist.value.i, &successful1); + } + lib_hash_table_remove(get_metadata_ht(), lib_int_elem(key_as_int)); + free(metadata); + free(object); +} + +void retain(obj *object) { + if (!object) return; + uintptr_t key_as_int = (uintptr_t)object; + lib_option_t option = lib_hash_table_lookup(get_metadata_ht(), lib_int_elem(key_as_int)); + if (option.success) { + metadata_t *metadata = (metadata_t *)(option.value.p); + metadata->rc++; + } +} + +void release(obj *object) { + if (!object) return; + metadata_t *metadata = get_metadata(object); + if (!metadata) return; + else if(metadata->rc > 0) { + metadata->rc--; + } + if(metadata->rc == 0) { + if(!release_in_progress){ + schedule_task_manager(object, 0); + } + else { + add_to_schedule(object); + } + } +} + +void cleanup() { + schedule_task_manager(NULL, SIZE_MAX); +} + +static void free_all() { + cleanup(); + lib_linked_list_destroy(get_schedule_linked_list()); + schedule_linked_list = NULL; + lib_hash_table_destroy(get_metadata_ht()); +} + +void shutdown() { + set_cascade_limit(STANDARD_CASCADE_LIMIT); + free_all(); +} + +size_t get_cascade_limit() { + return CASCADE_LIMIT; +} + +void set_cascade_limit(size_t size) { + CASCADE_LIMIT = size; +} + +void str_dummy_destructor(obj *o) { +} + +char *rc_strdup(char *src) { + char *str; + char *p; + int len = 0; + while (src[len]) len++; + str = allocate(len + 1, str_dummy_destructor); + p = str; + while (*src) + *p++ = *src++; + *p = '\0'; + return str; +} + diff --git a/src/ref.h b/src/refmem.h similarity index 96% rename from src/ref.h rename to src/refmem.h index 8beb496..195f6ac 100644 --- a/src/ref.h +++ b/src/refmem.h @@ -1,133 +1,133 @@ -#pragma once -#include -#include -#include -#include -#include "lib/lib_hash_table.h" -#include "lib/lib_linked_list.h" -#include "lib/lib_common.h" - - -// Void pointer used for allocation -typedef void obj; - -// A destructor function pointer -typedef void(*function1_t)(obj *); - -// The data we store when allocating a object -struct metadata { - uint8_t rc; // Reference count - function1_t destructor; // Function to call before freeing - size_t size; // Total size of the user allocation -}; -typedef struct metadata metadata_t; - -/** - * @brief Increases the reference count for a given object. - * - * @param object A pointer to the object whose reference count should be incremented. - */ -void retain(obj *object); - -/** - * @brief Decreases the reference count for a given object and deallocates it if the count reaches zero. - * - * @param object A pointer to the object whose reference count should be decremented. - */ -void release(obj *object); - -/** - * @brief Retrieves the current reference count of an object. - * - * @param object A pointer to the object. - * @return The reference count of the object, or 0 if the object has no metadata. - */ -uint8_t rc(obj *object); - -/** - * @brief Allocates memory for an object and associates it with metadata. - * - * @param bytes The number of bytes to allocate for the object. - * @param destructor A function to be called before deallocating the object. - * @return A pointer to the allocated object, or NULL if allocation fails. - */ -obj *allocate(size_t bytes, function1_t destructor); - -/** - * @brief Allocates memory for an array of objects and associates it with metadata. - * - * @param elements The number of elements in the array. - * @param elem_size The size of each element in bytes. - * @param destructor A function to be called before deallocating the object. - * @return A pointer to the allocated array, or NULL if allocation fails. - */ -obj *allocate_array(size_t elements, size_t elem_size, function1_t destructor); - -/** - * @brief Generates metadata for an object. - * - * @param destructor A function to be called before deallocating the object. - * @param size The size of the object. - * @return A pointer to the generated metadata, or NULL if allocation fails. - */ -metadata_t *metadata_generate(function1_t destructor, size_t size); - -/** - * @brief Deallocates an object by adding it to the schedule and triggering destructors as needed. - * - * @param object A pointer to the object to deallocate. - */ -void deallocate(obj *object); - -/** - * @brief Sets the cascade limit for freeing objects. - * - * @param size The new cascade limit. - */ -void set_cascade_limit(size_t size); - -/** - * @brief Retrieves the current cascade limit for freeing objects. - * - * @return The current cascade limit. - */ -size_t get_cascade_limit(); - -/** - * @brief Cleans up scheduled tasks by freeing all eligible objects. - */ -void cleanup(); - -/** - * @brief Shuts down the memory manager by freeing all resources and clearing metadata. - */ -void shutdown(); - -/** - * @brief Retrieves the global metadata hash table. - * - * @return A pointer to the metadata hash table. - */ -lib_hash_table_t *get_metadata_ht(); - -/** - * @brief Retrieves the global schedule linked list. - * - * @return A pointer to the schedule linked list. - */ -lib_list_t *get_schedule_linked_list(); - -/** - * @brief Creates a new reference-counted copy of the input string. - * - * @param src A pointer to the source string to duplicate. - * @return A pointer to the duplicated string. - */ -char *rc_strdup(char *src); - -/** - * @brief A dummy destructor for strings. - * - * @param o A pointer to the object. - */ -void str_dummy_destructor(obj *o); +#pragma once +#include +#include +#include +#include +#include "lib/lib_hash_table.h" +#include "lib/lib_linked_list.h" +#include "lib/lib_common.h" + + +// Void pointer used for allocation +typedef void obj; + +// A destructor function pointer +typedef void(*function1_t)(obj *); + +// The data we store when allocating a object +struct metadata { + uint8_t rc; // Reference count + function1_t destructor; // Function to call before freeing + size_t size; // Total size of the user allocation +}; +typedef struct metadata metadata_t; + +/** + * @brief Increases the reference count for a given object. + * + * @param object A pointer to the object whose reference count should be incremented. + */ +void retain(obj *object); + +/** + * @brief Decreases the reference count for a given object and deallocates it if the count reaches zero. + * + * @param object A pointer to the object whose reference count should be decremented. + */ +void release(obj *object); + +/** + * @brief Retrieves the current reference count of an object. + * + * @param object A pointer to the object. + * @return The reference count of the object, or 0 if the object has no metadata. + */ +uint8_t rc(obj *object); + +/** + * @brief Allocates memory for an object and associates it with metadata. + * + * @param bytes The number of bytes to allocate for the object. + * @param destructor A function to be called before deallocating the object. + * @return A pointer to the allocated object, or NULL if allocation fails. + */ +obj *allocate(size_t bytes, function1_t destructor); + +/** + * @brief Allocates memory for an array of objects and associates it with metadata. + * + * @param elements The number of elements in the array. + * @param elem_size The size of each element in bytes. + * @param destructor A function to be called before deallocating the object. + * @return A pointer to the allocated array, or NULL if allocation fails. + */ +obj *allocate_array(size_t elements, size_t elem_size, function1_t destructor); + +/** + * @brief Generates metadata for an object. + * + * @param destructor A function to be called before deallocating the object. + * @param size The size of the object. + * @return A pointer to the generated metadata, or NULL if allocation fails. + */ +metadata_t *metadata_generate(function1_t destructor, size_t size); + +/** + * @brief Deallocates an object by adding it to the schedule and triggering destructors as needed. + * + * @param object A pointer to the object to deallocate. + */ +void deallocate(obj *object); + +/** + * @brief Sets the cascade limit for freeing objects. + * + * @param size The new cascade limit. + */ +void set_cascade_limit(size_t size); + +/** + * @brief Retrieves the current cascade limit for freeing objects. + * + * @return The current cascade limit. + */ +size_t get_cascade_limit(); + +/** + * @brief Cleans up scheduled tasks by freeing all eligible objects. + */ +void cleanup(); + +/** + * @brief Shuts down the memory manager by freeing all resources and clearing metadata. + */ +void shutdown(); + +/** + * @brief Retrieves the global metadata hash table. + * + * @return A pointer to the metadata hash table. + */ +lib_hash_table_t *get_metadata_ht(); + +/** + * @brief Retrieves the global schedule linked list. + * + * @return A pointer to the schedule linked list. + */ +lib_list_t *get_schedule_linked_list(); + +/** + * @brief Creates a new reference-counted copy of the input string. + * + * @param src A pointer to the source string to duplicate. + * @return A pointer to the duplicated string. + */ +char *rc_strdup(char *src); + +/** + * @brief A dummy destructor for strings. + * + * @param o A pointer to the object. + */ +void str_dummy_destructor(obj *o); diff --git a/test/test.c b/test/test.c index c2f9084..d4e1c5e 100644 --- a/test/test.c +++ b/test/test.c @@ -1,4 +1,4 @@ -#include "../src/ref.h" +#include "../src/refmem.h" #include #include #include From cdbfe188a8de9693d775a7c60df2d9bfada77877 Mon Sep 17 00:00:00 2001 From: Truxilla <149168007+Truxilla@users.noreply.github.com> Date: Mon, 13 Jan 2025 22:24:42 +0100 Subject: [PATCH 3/4] added readme --- Makefile | 18 +++--- all | Bin 64208 -> 38320 bytes demo/makefile | 128 +++++++++++++++++++++++++---------------- obj/backend_tests | Bin 0 -> 135424 bytes {demo => obj}/frontend | Bin obj/test/test | Bin 0 -> 38320 bytes proj/project_report.md | 55 +++++++++--------- readme.md | 15 +++++ 8 files changed, 133 insertions(+), 83 deletions(-) create mode 100644 obj/backend_tests rename {demo => obj}/frontend (100%) create mode 100644 obj/test/test create mode 100644 readme.md diff --git a/Makefile b/Makefile index dae4388..e91b585 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ C_COVERAGE = gcov -abcfu --coverage R_COVERAGE = gcovr -r . --html --html-details -o coverage.html # Source and object files -REF = src/ref.c +REF = src/refmem.c TEST_SRC = test/test.c HASH = src/lib/lib_hash_table.c LIST = src/lib/lib_linked_list.c @@ -18,7 +18,7 @@ OBJ_DIR = obj SRC_DIR = src LIB_DIR = lib TEST_DIR = test -REF_OBJ = $(OBJ_DIR)/ref.o +REF_OBJ = $(OBJ_DIR)/refmem.o TEST_OBJ = $(OBJ_DIR)/$(TEST_DIR)/test.o HASH_OBJ = $(OBJ_DIR)/$(LIB_DIR)/lib_hash_table.o LIST_OBJ = $(OBJ_DIR)/$(LIB_DIR)/lib_linked_list.o @@ -35,13 +35,13 @@ $(OBJ_DIR)/test/%.o: test/%.c # Target for the reference executable all: $(REF_OBJ) $(TEST_OBJ) $(HASH_OBJ) $(LIST_OBJ) - $(C_COMPILER) $(C_LINK_OPTIONS) $(REF_OBJ) $(TEST_OBJ) $(HASH_OBJ) $(LIST_OBJ) -o $@ $(CUNIT_LINK) + $(C_COMPILER) $(C_LINK_OPTIONS) $(REF_OBJ) $(TEST_OBJ) $(HASH_OBJ) $(LIST_OBJ) -o $@ $(CUNIT_LINK) run: ref - valgrind --leak-check=full --show-leak-kinds=all ./ref + valgrind --leak-check=full --show-leak-kinds=all ./refmem demo: - $(MAKE) -C demo start + $(MAKE) -C demo run_frontend memdemo: $(MAKE) -C demo full_val_frontend @@ -50,10 +50,14 @@ memdemo: test: $(REF_OBJ) $(TEST_OBJ) $(HASH_OBJ) $(LIST_OBJ) $(C_COMPILER) $(C_LINK_OPTIONS) $(REF_OBJ) $(TEST_OBJ) $(HASH_OBJ) $(LIST_OBJ) -o $(OBJ_DIR)/test/test $(CUNIT_LINK) $(OBJ_DIR)/test/test + $(MAKE) -C demo backend_tests + $(MAKE) -C demo run_backend_tests memtest: $(REF_OBJ) $(TEST_OBJ) $(HASH_OBJ) $(LIST_OBJ) $(C_COMPILER) $(C_LINK_OPTIONS) $(REF_OBJ) $(TEST_OBJ) $(HASH_OBJ) $(LIST_OBJ) -o $(OBJ_DIR)/test/test $(CUNIT_LINK) valgrind --leak-check=full --show-leak-kinds=all $(OBJ_DIR)/test/test + $(MAKE) -C demo backend_tests + $(MAKE) -C demo full_val_backend_tests gdb: ref @@ -69,6 +73,6 @@ coverage: cov # Clean up generated files clean: - rm -f obj/*.o obj/*/*.o obj/test/test *.gcda *.gcno ref* cov* test.c.* + rm -f obj/*.o obj/*/*.o obj/test/test obj/backend_tests obj/frontend *.gcda *.gcno ref* cov* test.c.* -.PHONY: demo \ No newline at end of file +.PHONY: demo all \ No newline at end of file diff --git a/all b/all index f97bab13a953f089636cccfb45700f4637a6f6ca..d9b5d16b388e99bebfc88c2f8c0145482302ccdf 100644 GIT binary patch delta 5337 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 RUPp{e{TlgSU#hxi{Vx&oqVxa& literal 64208 zcmeFa33yc1*#~~_Ozz}PGD#-OWCb$pVF^jt3d)iIfdK+U0UH+_LNbs@NMbU>Vnr!I zYZ{~AUPZ-EYw1_9*jkH%EN{2inWR2=Az z!@p7qjxCSa1i&bDiDySiblFttq3k2N6{9pXq>|`*`{)S*Vw8$ow24lms%*!W&rcC} zMrpuJd6fdL#FXJ|(QlMiI`U2FDgiHDA6**$I4AvM&{31C+QNPMFt8T46rJXrg`kyk0{!rvEsV#~{<9!6=%y8v|L zm+$&9hWSD%ueWj7Fa2ngG~V6;GS`1rkV9esaqXpF&wWD*X2h~5}t zqn(Zl;gJ0|EPX%)T&KQF{L8|>Y2|O8dg|j_u6`}>>Z*6Htm;#3pZO1T_xSladgauP zg3p0~p86N{f}etZZxjd7cojuYd{*|-zq^MxmNU3ZlZi9@|C zbC!OOfsC?F_Q#_xO=4)XrQhnowU&M(M-#yYOF!=qm<#f(rQf>lY_{~1Y~yp6rQh%! z!M0iYF#zUgyQN=lSs1p{(w}HzE6OfQKL*zP?6>qMo4ty1$kK1b1c47*`cp0V|Ed1R z1OM^Be?0IX5B&ej17}nEeeG*IrTaRxcbXK%cisM=t?RI_?K%Bfc0|{>(da(YHFyk) zlzfHo>j-k@#D`s7U7NX03-Fl}ubFLHc+Z?TV76(&J#*qQvrQX?GbbJ}+qCeWIkClT z(}H{E#1G9jEwpD&Txqsxfjx7g+HBLpdgjChW}6n&GbhT-HZ7!QPL!B!+K`+%(cf&- zf_mmes?mnE?>CaQGZeNL?a49iaWU<}nD*e9cHfw`C#Ibg)7E0z|HS10t3F@Fv_Fe! zACGCjAJcx*+AjHQcKd6W``SP9wH-TMxu~L3yJHeUp))C;i^)X;6{XAbE0BD-+1EMw zLsWd7+8?QycrNHc=-fnggpRZ8XiEMDcvE>+mcW0E@yGo)6~n&qwV(DK_YFX%1=*xCgryMOP;j?JIc>lIyy8P zc*3?&zOU2s1{m!n^I+C5P!FqvNg3@=4JbOa-%|n9bbxOp@a!T6{}%n5qnPfHn8fs2 z3)72;>XAWA)h?KBL=i=c1BxkS2;qM`it#TH_;aH1+fI35au_Bb-AmW1_R(YwKmX6J zE?;~3IbYlQb4nxdg% z00v+fF4+&PU8o(RlRdFI)c%Z*`9sw%U;iUM=V4#_v)mK@6hr50Kj7;uN8cZP?XUXU z4~FLrL99Pfez@(lx@mt<>J|r1M|~ZkaIJ65Se6#l!u$RK^0w!EmszxPw-n(}Y4Zefrr^))0<1yB7 zZTV@Ricuhg=pRP&V0bjVhcQU8bd?}k``XG+t4z_hU-wNc54Y~w9AkGCB4c}OWVEf{ zt_0VCa69DeG6H1Rw*<(GG{Ug~G7|H{43N-B@I!c(Q{drWsT=h}Fljs5hkWgCksbfQ zu$_$CjL|_Sg^&nXgwWMrvy-YUAwrIuT!BR_q?SVJA*<8QVLBZw57RKAJWA!s z^Ij28u#1J7;y-?7ww&MS|R%CXuk4TSUWAOpZYc+b>kToCb|Y_l14r zlW-Hwa@oQ8?f5zJ4BX8wr_8Y!F@g9H@$e^NfNWLK5eOS$c(lFuJT(pY6<8nJd93gC z!b8Nk?YZJh%PxybKBQ@wlC7_OF-Z^mQhv$di7CY$=cEdGP&wj7GIA|Qdz>;Uo6f>W zFxw8D5#m%H3S2O)j+=}+@?I&5@ZozVKAEl$;1a0e!~Ngl z!*6&Rt|=LE}~Ve z#=$Cdiy0Dh%W7vOh4;A|j5a3En3N~9rdmZ2t0boznE(!kmm)8nOf$F-!ZZ}VjKrJo z;0uVqE-`ybfNt5Ih≦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 JBTwPB_#b) diff --git a/demo/makefile b/demo/makefile index 66ee0af..38772c9 100644 --- a/demo/makefile +++ b/demo/makefile @@ -1,81 +1,107 @@ -clean: - rm -f *.o frontend backend_tests old_hash old_list *.gcno *.gcda *.gcov backend_tests_coverage - -frontend: user_interface/frontend.c generic_utils/utils.c generic_data_structures/linked_list.c generic_data_structures/hash_table.c business_logic/shop.c business_logic/merch.c business_logic/cart.c business_logic/common.c - gcc -g user_interface/frontend.c generic_utils/utils.c generic_data_structures/linked_list.c generic_data_structures/hash_table.c business_logic/shop.c business_logic/merch.c business_logic/cart.c business_logic/common.c ../src/refmem.c ../src/lib/lib_hash_table.c ../src/lib/lib_linked_list.c -o frontend -w - -run_frontend: - clear; ./frontend +# Define compiler and options +CC = gcc +CFLAGS = -g -Wall -pedantic -Wextra -w +LDFLAGS = -lcunit -lm +OBJ_DIR = ../obj +SRC_DIR = ../src +GEN_UTILS_DIR = generic_utils +GEN_DS_DIR = generic_data_structures +BUS_LOGIC_DIR = business_logic +TESTS_DIR = tests +UI_DIR = user_interface +LIB_DIR = ../src/lib + + + +# Source files for frontend +FRONTEND_SRC = $(UI_DIR)/frontend.c $(GEN_UTILS_DIR)/utils.c $(GEN_DS_DIR)/linked_list.c \ + $(GEN_DS_DIR)/hash_table.c $(BUS_LOGIC_DIR)/shop.c $(BUS_LOGIC_DIR)/merch.c \ + $(BUS_LOGIC_DIR)/cart.c $(BUS_LOGIC_DIR)/common.c $(SRC_DIR)/refmem.c \ + $(LIB_DIR)/lib_hash_table.c $(LIB_DIR)/lib_linked_list.c + +# Source files for backend tests +BACKEND_TEST_SRC = $(BUS_LOGIC_DIR)/common.c $(BUS_LOGIC_DIR)/shop.c $(BUS_LOGIC_DIR)/merch.c \ + $(BUS_LOGIC_DIR)/cart.c $(TESTS_DIR)/backend_tests.c $(GEN_UTILS_DIR)/utils.c \ + $(GEN_DS_DIR)/linked_list.c $(GEN_DS_DIR)/hash_table.c $(SRC_DIR)/refmem.c \ + $(LIB_DIR)/lib_hash_table.c $(LIB_DIR)/lib_linked_list.c + +# Targets +.PHONY: all clean run valgrind debug test + +all: frontend backend_tests + +# Frontend target +frontend: $(FRONTEND_SRC) | $(OBJ_DIR) + $(CC) $(CFLAGS) $^ -o $(OBJ_DIR)/frontend $(LDFLAGS) + +run_frontend: frontend + clear + ./$(OBJ_DIR)/frontend -val_frontend: - valgrind -s ./frontend +val_frontend: frontend + valgrind -s ./$(OBJ_DIR)/frontend -full_val_frontend: - make frontend; clear; valgrind -s --leak-check=full ./frontend +full_val_frontend: frontend + clear + valgrind -s --leak-check=full ./$(OBJ_DIR)/frontend clean_frontend: make clean; make frontend; make run_frontend -start: - clear - make clean_frontend - -clean_val_frontend: - make clean; make frontend; make val_frontend - -clean_full_val_frontend: - make clean; make frontend; make full_val_frontend +# Backend tests target +backend_tests: $(BACKEND_TEST_SRC) | $(OBJ_DIR) + $(CC) $(CFLAGS) $^ -o $(OBJ_DIR)/backend_tests $(LDFLAGS) -backend_tests: business_logic/common.c business_logic/shop.c business_logic/merch.c business_logic/cart.c tests/backend_tests.c generic_utils/utils.c generic_data_structures/linked_list.c generic_data_structures/hash_table.c ../refmem.c - gcc -g -Wall -pedantic business_logic/common.c business_logic/shop.c business_logic/merch.c business_logic/cart.c tests/backend_tests.c generic_utils/utils.c generic_data_structures/linked_list.c generic_data_structures/hash_table.c ../refmem.c ../lib/lib_hash_table.c ../lib/lib_linked_list.c -lcunit -o backend_tests +run_backend_tests: backend_tests + ./$(OBJ_DIR)/backend_tests -run_backend_tests: - ./backend_tests +val_backend_tests: backend_tests + valgrind -s ./$(OBJ_DIR)/backend_tests -val_backend_tests: - valgrind -s ./backend_tests - -full_val_backend_tests: - valgrind -s --leak-check=full ./backend_tests +full_val_backend_tests: backend_tests + valgrind -s --leak-check=full ./$(OBJ_DIR)/backend_tests clean_val_backend_tests: make clean; make backend_tests; make val_backend_tests -test: - clean_val_backend_tests +test: clean_val_backend_tests +# Debug target debug: backend_tests - gdb ./backend_tests --tui + gdb ./$(OBJ_DIR)/backend_tests --tui -backend_tests_cov: business_logic/common.c business_logic/shop.c business_logic/merch.c business_logic/cart.c tests/backend_tests.c generic_utils/utils.c generic_data_structures/linked_list.c generic_data_structures/hash_table.c - gcc -g -Wall -pedantic business_logic/common.c business_logic/shop.c business_logic/merch.c business_logic/cart.c tests/backend_tests.c generic_utils/utils.c generic_data_structures/linked_list.c generic_data_structures/hash_table.c -lcunit --coverage -o backend_tests_coverage +# Coverage target +backend_tests_cov: $(BACKEND_TEST_SRC) | $(OBJ_DIR) + $(CC) $(CFLAGS) $^ -o $(OBJ_DIR)/backend_tests_coverage --coverage $(LDFLAGS) -cov_run: - ./backend_tests_coverage +cov_run: backend_tests_cov + ./$(OBJ_DIR)/backend_tests_coverage gcov: - gcov -b -c backend_tests_coverage-backend_tests.gcda > coverage.txt + gcov -b -c $(OBJ_DIR)/backend_tests_coverage.gcda > coverage.txt -old_hash: - gcc -g -Wall -pedantic generic_data_structures/hash_table.c generic_data_structures/linked_list.c generic_data_structures/hash_table_tests.c ../refmem.c ../lib/lib_hash_table.c ../lib/lib_linked_list.c -lcunit -o old_hash - valgrind -s --leak-check=full ./old_hash +# Old hash target +old_hash: $(GEN_DS_DIR)/hash_table.c $(GEN_DS_DIR)/linked_list.c $(GEN_DS_DIR)/hash_table_tests.c $(SRC_DIR)/refmem.c $(LIB_DIR)/lib_hash_table.c $(LIB_DIR)/lib_linked_list.c + $(CC) $(CFLAGS) $^ -o $(OBJ_DIR)/old_hash $(LDFLAGS) + valgrind -s --leak-check=full ./$(OBJ_DIR)/old_hash -old_list: - gcc -g -Wall -pedantic generic_data_structures/linked_list.c generic_data_structures/linked_list_tests.c ../refmem.c ../lib/lib_hash_table.c ../lib/lib_linked_list.c -lcunit -o old_list - valgrind -s --leak-check=full ./old_list +# Old list target +old_list: $(GEN_DS_DIR)/linked_list.c $(GEN_DS_DIR)/linked_list_tests.c $(SRC_DIR)/refmem.c $(LIB_DIR)/lib_hash_table.c $(LIB_DIR)/lib_linked_list.c + $(CC) $(CFLAGS) $^ -o $(OBJ_DIR)/old_list $(LDFLAGS) + valgrind -s --leak-check=full ./$(OBJ_DIR)/old_list -old_list_full: - gcc -g -Wall -pedantic generic_data_structures/linked_list.c generic_data_structures/linked_list_tests.c ../refmem.c ../lib/lib_hash_table.c ../lib/lib_linked_list.c -lcunit -o old_list - valgrind -s --leak-check=full --show-leak-kinds=all ./old_list +old_list_full: old_list + valgrind -s --leak-check=full --show-leak-kinds=all ./$(OBJ_DIR)/old_list +# Hidden tests tests_hidden: frontend @GREEN='\033[1;32m'; \ RED='\033[1;31m'; \ NC='\033[0m'; \ - for file in ./user_interface/ui-tests/*.txt; do \ + for file in ./$(UI_DIR)/ui-tests/*.txt; do \ base_name=$$(basename $$file .txt); \ echo "Running test: $$base_name"; \ - valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./frontend < $$file > temp_output.txt 2>&1; \ + valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./$(OBJ_DIR)/frontend < $$file > temp_output.txt 2>&1; \ if grep -q "ERROR SUMMARY: 0 errors" temp_output.txt; then \ echo -e "$$base_name $$GREEN PASSED $$NC"; \ else \ @@ -85,3 +111,7 @@ tests_hidden: frontend done @rm -f temp_output.txt +# Clean target +clean: + rm -rf $(OBJ_DIR) *.gcno *.gcda *.gcov coverage.txt + rm -f frontend backend_tests old_hash ol diff --git a/obj/backend_tests b/obj/backend_tests new file mode 100644 index 0000000000000000000000000000000000000000..ba6bd7ba5043fdf0cd9cda50d6a19a270f073f3a GIT binary patch literal 135424 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%0ARxUw&uP?J=?n(;MSdd zn%tu+{WbaswtLLHHzklP+RIigTW>UmGDz=8Hl(AZ6(Tm=O)Zk198br&kKSr*hTFFG z4#>L6l||{Y)xMx*03JQFn=qynOiO}SUd?z|9X;Kx&DLP&s==+B+WJFM&;M zYh_65E?&5B@w#>VylS;rklt0~rHSBk-&kkbx-jifCL>?9nh4M)N2*GKmBeiTR~{>) z{w>Mv&HYL8)LTh{J!3#kFI=#Q*QeZc7)M+sA>W6U1e#Bf7;t9StWF4x9#Mk*uC-)~ z7O!2qdM$`gu4A*vf}qt1&%Kh{yL@nK?}dCZHdhN;uE395`t&DM7C&qU~{q+bA^?S+cHH%%- zZmfeVo-{1lFyRvin_W>8fyKgYT}$^sUzbHAcNKhpUM0vf+T!&e2@_S@+}GUOK@Yt! z*|fY`*WA@Th~@sWb*-J7@d}7ud$VIpxtqG0yWy|4b#ETvcKyB0@UVG(r{TkDz_MR$ zp-E>e=G$H@+u(j6=zZI^P6UQ@4Y!$gQ>>m%S0XS(3>$3IK3!{OUHB%L zwR&{1yOw}X^%|9r!6JNk5!Q_s!eJva6W?uNSs31`8AA<^g8J^I$Sk;sV2z7HGW2m9 ziW@M$&7gQY1#oaXz-%H^uo<=*{?l6c)QoEG-U(sGsulv+I=FS~PWFA63^c;3PA|M# zwRp96_Myv0#xqX$;)sRIZ@9W3Yg49_2*D(-q*$cvBd`{0`Np?UI(#jEYXD5qHQoINY%K|7SygH18m=%b2AGD3vF5cFG#X?8T;_YKd6q6hZe|&{Gpry@ zGCd7oy1gpkDM=IAO@sJC5?(26hbKkD!^Q{kT9^ttO~6L<6kF z#C{GVmV|v+rZyF100i;yDqeHs>4}y`d={!1{To^jpmXIPFsqwUS@eI%;zqPr$c{8kXAG$^H z0#C)3=Khvu1iPEJay&8}t7T|UHuv>4lRrYftTgEA+zLmD{8m})&<;iy@ALo-&8!yD z*D7o=h!Kat6u23lLqD@wM`pA`YKV46UkA$2`DBug#?AB&CcLy^lQ9pv^cq9*~(>D7kStw70DVv&Vj(N(G?V+ z^U6df`BKkguhW@qW{8YjGB6og+CXOHibZiVjo@cC))vOCCtFIadl`AI!{a^lLmMb! zg)?d!@w*()HqCXU2u3*KzQmCnaX;JlafC56`)2jfhL^7gDabwr5zGqbiwR9qrt)s#BQ$4cR05+>M8Flnks zRUyY0;^(mFdQ9KHr0-AayOf^ce?LAd8K)Q6GA=*9P&sqNe81H=Vt$tO?h*5qb!f!= zfc5-{`PtT&a4tFX^5fT3-%TGG$hiDg(E8Gd`QQeAHZAk=Te;TrBj$(jVfM`0bRIL$ zN{pDFZ}pnr*!48?TLsph5%a^=m++HgnU~)xv~IgAGneq9@}ZIPqt=@bj+7s>?*HUS z`9+rV>yh${t?-EXC02aI{J0f=Z6rAOqU-A;<(FCU5%bOOrlq&>TNUXUI_0os-e@4}` zBgj<0DI@=UH{(6sB0y^VaT|N0?3;L=}-wCMeBs{hDn z$=@S4s|xv4-#IK9c{=}mbp3TYf6qCR@q*58)A<`FO2$h%e>?IC z@1etzVfw`%U_<_wbUuDFiLX!S`ajY6M(w|>^R0WNp6Tz4IzOTF>08Kjy@~vh`jzDy zIlmWnbENtq)F*y^w^iV_%gu`G{O|NhhGvtMJO!L{bba%Fn(0@a&X4O~I>m1y^0i9m zU!wD`()m~F{F6H0(6b%+Bhh~o5RqOawB0af{SpiWoCIlt5jXTUN2ef}D0Z~FTn>JvYIq4O`+@V}(;FjS ze^%!kKKw@KS6wR=zo_fm7#G6(lFr|*^Xa#%DS!Q5$#`7nkJ0(L`y?Z&^JgKSJ4|H~& z0u1iVpX2=D^YSwc zXZXAsDxh&3?r;1Q^&=SHg*OP{hR<*6{F}9(fVaE&%EF;^W2wez zTAhDQt7Od4`Ac>F3*#ii*u6H+*OffC?Ye&HO3C~tXIdoNdiWG@{z=zg z+9?(9(+d1!o&WmHl7Fj)^R~`ER}(l<=l_45T@8>|RTaOYty&_aHM=0mrjelXXFp(f zCD~XO7B^Q=SQK#RvCDoU?81I1;0MkKk%%xxqkvF4qo!E+5ozQ$5#~6Ugpm}ZsYI3^ z11(u%W5jmOJ-_qbefPaTH2r6G?|Z*@&bjxUd+xdS|NiIP*Pj%UrU!Z{jMe9YTZQmJ z(3b-D-!wY~c7urB1OmJC%`u?7yK$z@+t5;@v7ZnX#c<*(c9yrgi!t4CBP4T zS8#nPb2;!?-GW~RIoAXK*IdEXU(L0+VDA48(EG2nzB>#3X3)1`ywI?+pJ#x-Hbc($ z!am;ve)(YFQkcFh^3SIo&Uicyf*(U+MgVWk6#;*MoC@F@$^@7VJiBvW_-+_- zFX}x8yst!nO~417C3<_lN`M~V`M{qUDZu5xPq2UMm;4?y*3yH>DW*V9VVi(o!?kY$ z|0e|h9QaMZfBXdjCIasQejCOq((%n|i-X819s~V4IFb)=?PtJuqh8h9E5JWNz2iXt z2Jk}|kJ_Fi7I!Md;b~`!KHr@xz;@CXe}(}6+b}uTuaU*T$2JOnpA@FX;y7`NS)lKQ z9&W|8cHp|r|JA^k10SC!z<%KO1OM|H0d#%4)#4y>ikCpYHzS~~&;JPgr&u^^|Mmi3 z4B!pO8bDw5d7Q4eSpY2W%q75&FBW_{=&uC67YmS8z-Iz4yj_6Rz;6cLb&CK~Fdo+e zFM;9A1pOnx*L+og9T<=Nz=qpd+9kO9=e@u$gk7Pz=1;(PVSd4|F&_Ybbdkup0qyAn z{`i#NTIhY0i7;-8wPGOFw4|qHhfV*Pd*NIuh_UVzzekU2{S7Vz^3XM5g(2I}SE zz>mN`>wR4b{LI@#fZ{WNuWAxp$3;8va?G>Zo;!j66$0Sq%mctTK|a)No(29e08C@% zWx_vCcVHfpde4x;{2ug2<_n;9dl>km8w9@x^rxRIdiXLN$wk1=0shYU0*nHl3%nNe zgMp6#e*FvqwB8!vB>>dVHvpgW4WaKr|E>hyTOs&Eu-gZKztARlkrd`B;6r8!fXik- zaEfEHA51^y1K))8fx4Da>1-@BNMdJ-|N!-aS@;!PsiGb@0P#Q1_+G#h{~+#+%? z9hxTzXFdDRho1+1!5pFAhILL4@U3?XJ^*^y2YfX8{T8`w-Uq(6Qvmg!G}x_uejgJx zrg<|I_>+)R0Xc=hM?e8^D`pb#$-{(D<;(`I+W=k;IrD+2CR zFTW+g5a9O!Uk3Xx0R9MY-KphEz_$UPxln+4!1nnXIRfpYyigSze|6ac!Al1V6kFH=@fQkYIeIk;`D5>kW+kERYz z3zeYJfPy5$Gm5vNz<3*d1kx~<840H;DXp2}lHyWH@1e%05|kE<&XNV0PF_?H<=Jt9 zS2|TmiOqqdO2gzXH&f09IpDrCMkcu+se(&NugFqkVL_G)MUY2ONNALyc#7VI6-!)+AS_BwefIaJd#zGyr(e{@L`R%Y8vHj1(T*s zq!jHSJ`5;}Y~n0RJE^XWU!ffrDDFN8Xd8!M(p7;-xN71w6HKm|I-#N_m|9geeNt^u zTQQ+#QjikO7f@(Y{k&jaXSW@qoZ~?$>hyM0j& zBx7+>tYZt5&B1#(#G9JX1;=9gu{$tpFOZU{oZ2O{Dwd8R!kxGv319TZYe-X2U3(2R zSlx8(HI?k7Yi$au&yyOUrh@2QwVsBdFhSh}T$?lG3rEmdLN|)@HVifmhg8}b*QYNE z6))y|@Hk~^z^t2s6?NjN(kYX-r3q;?&)M)_N`BzEkBo^M==Pf3SRu@`wS1gri;Qtc zay*NeOqG3$54L?;yuRW)g4e;kF_Cj3Y5w&?QxBs zhZH5w@m4alJ;zN!6XgI#l1JMv34H+!#&&+ZJ)HOwZmOX(i$h}5r7?g-9cjZO1By$w`%%P|!}lO{ zS=s1it8fR#tweq|VNx<4gvGIbM4SrlbOGmtxkJ&<4^0S)1%)QAqEDTQ9VKZ$aL;6E zrrsYbE^MWZA=T_W?+(;aW!+N%sdh3|+9{Xf>svj0cf$T7U&Iz3<#}2qVUdwY#Y}cT z-y@6aq$MV26vT~{7US{)b6x?6Cvx;eBa${2igS=bCZ{wa6d&mHSwe-#_VY8jShNJ%`yApN zXkR3|OHsi4IHforvV+8;1-BOFy|}wlC2}qjgFTu0oX`g{8QdXYhe@<=fJ|hT0CSxn z-e~2!w<@=kr`)JO_3wnKCvHBBXm?h_JZzymsu3?(XY-BC*6icO4ao?kVHD;Gg{eo} zOQ9nQn=cKsjv7Nh+TO&~Qn(?6wS0HQXfspNw2-#JgKsKP2zywW+=xAO#+FV0_x2s} zg@s=UVB6Mh@jY`QzU(Z*Y3j`8D3d2af3q%Mvf65>KMAG}f_mBtNWT5p40TU*7N;bu z?u2b(&Q4RMO@NW*k2LLMcEmU2bSoQ&m@p52cP(UVavi=VP+uMa*wV{C*|5b==dvH z>K8I$2}SD^;N2?C^08fUk`;*orx|KuTNE9Nu~mD@Y@pu_-K`D0c7?+`*`UacXnl?s zfjw~xQYsF;Zc=JkVGzt)QpZmw?CvUY8}b_IyXM#&;l}A2R-72}(T;91Jw$nw<=ntqp)GCREero6W|Ovtu=xhNW#(g_N{$o4rCiQFL;uyn7PRH5yWN z%z&dsv`J;gPJ0t`GC2@=h0-`um*LfXDQDYWQ*gne?apW#H2?Kctic3ImIM_;*&9 zeJTfiI={kS3{aTNf{PV~O zhhOu}v>eaO^zqv-s4@IA5bIRsg?VXb3&jBtYW@EG^UvzcKLK=_zoz9u+%WUA&V2rd z31bqKPd^>W2c`a=1=QB1$6RivKbJord|F$Dty ziu!kW{5$FQSN>?ZUw=RoI8+Z#%`fP{y?@Qu)3U!3qV&hlOW+Ut{~-{f{09#X=i}>R z4_)K>m0$D!wA>zctO)Vzf79dFJV7l7dIq5OBhrld3ms6%j~#=IY5v1mZ}C}VZ*mr$ ztDL{n1qyKq`8D5S;Qz?~AL8X(gxd)76Z62YisA9cAFWsQ_#|PhzmUI|sc5XcBjx*2 zg#VRa%N$~M`NKHGgTkVIN(CsNo}WX^jD__d1>Zp_^Q8#?`~3DjsdTjzKWgHm4R z;oMgKXgQb;^jNOQ|H^|>4phU!MW1#=7XImngyHR#V9dflCJTRIi_|nU_vHMQS@^GA zF8tpvJ~{tX@ca5Z@T~AZuYnL=`{k-J9LKN6ZcXd<3F^!BY5Ck!u@$pZ`7acy7gNzp qf7<_QS3FIq?Fgm(KYCPZs@EU%anY}z!g^Bqr{zei&<&wzpZ~vHwyn1S literal 0 HcmV?d00001 diff --git a/demo/frontend b/obj/frontend similarity index 100% rename from demo/frontend rename to obj/frontend diff --git a/obj/test/test b/obj/test/test new file mode 100644 index 0000000000000000000000000000000000000000..d9b5d16b388e99bebfc88c2f8c0145482302ccdf GIT binary patch literal 38320 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 Date: Mon, 13 Jan 2025 22:26:43 +0100 Subject: [PATCH 4/4] added readme again --- readme.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/readme.md b/readme.md index fa33ebb..04ea500 100644 --- a/readme.md +++ b/readme.md @@ -8,8 +8,4 @@ make test - cleans, compiles and runs tests through valgrind with --leak-check=f make memtest - cleans, compiles and runs tests through valgrind with --leak-check=full flag make demo - cleans, compiles and runs frontend make memdemo - cleans, compiles and runs frontend -make clean- cleans all the object files (as well as unnecessary files) - - - - +make clean- cleans all the object files (as well as unnecessary files) \ No newline at end of file