From 79e3fdb620f0901aa44fa5de95acbd42b6c51668 Mon Sep 17 00:00:00 2001 From: lohhiiccc Date: Mon, 22 Jun 2026 18:18:19 +0200 Subject: [PATCH] feat: ft_list_remove_if --- Makefile | 3 +- src/ft_list_remove_if.s | 171 ++++++++++++++++++++++++++++++++++++++++ src/libasm.h | 1 + 3 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 src/ft_list_remove_if.s diff --git a/Makefile b/Makefile index 585be28..0e5ed79 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,8 @@ SRCS=$(SRC_DIR)/ft_strlen.s \ $(SRC_DIR)/ft_atoibase.s \ $(SRC_DIR)/ft_list_push_front.s \ $(SRC_DIR)/ft_list_size.s \ - $(SRC_DIR)/ft_list_sort.s + $(SRC_DIR)/ft_list_sort.s \ + $(SRC_DIR)/ft_list_remove_if.s OBJS=$(patsubst $(SRC_DIR)/%.s,$(OBJ_DIR)/%.o,$(SRCS)) DEPS=$(OBJS:.o=.d) diff --git a/src/ft_list_remove_if.s b/src/ft_list_remove_if.s new file mode 100644 index 0000000..a88dc07 --- /dev/null +++ b/src/ft_list_remove_if.s @@ -0,0 +1,171 @@ +global ft_list_remove_if +extern free + +struc list + .data resq 1 + .next resq 1 +endstruc + +section .text + + +;void ft_list_remove_if(t_list **begin_list, void *data_ref, +; int (*cmp)(void *, void *), void (*free_fct)(void *)) +;{ +; t_list *cur; +; t_list *prev; +; t_list *to_del; +; +; if (!begin_list || !cmp) +; return; +; cur = *begin_list; +; prev = NULL; +; while (cur) +; { +; if (cmp(cur->data, data_ref) == 0) +; { +; to_del = cur; +; if (prev) +; prev->next = cur->next; +; else +; *begin_list = cur->next; +; cur = cur->next; +; if (free_fct) +; free_fct(to_del->data); +; free(to_del); +; } +; else +; { +; prev = cur; +; cur = cur->next; +; } +; } +;} + +; void ft_list_remove_if(...) +; rdi: t_list **begin_list +; rsi: void *data_ref +; rdx: int (*cmp)(void *, void *) +; rcx: void (*free_fct)(void) + +; iter on list and remove current if cmp return 0 +; free_fct can be NULL +ft_list_remove_if: + + ; test begin_list + test rdi, rdi + jz .ret + + ; test cmp + test rdx, rdx + jz .ret + + ; rax = *begin_list + mov rax, [rdi] + + ; prev: r11 + xor r11, r11 + ;cur = r8 + mov r8, rax + + ;while cur +.L1: + test r8, r8 + jz .ret + + push rdi ; begin_list + push r8 ; cur + push r11 ; prev + push rdx ; cmp + push rcx ; free_fct + push rsi ; data_ref + + mov rdi, [r8 + list.data] + ; rsi is already set as data_ref + call rdx + + pop rsi ; data_ref + pop rcx ;free_fct + pop rdx ; cmp + pop r11 ; prev + pop r8 ; cur + pop rdi ; begin_list + + ; if ret of cmp == 0 goto del + test rax, rax + jz .del + +.no_del: + mov r11, r8 + mov r8, [r8 + list.next] + jmp .L1 + +.del: + ; to_del + mov r9, r8 + + ; r10 = cur->next + mov r10, [r8 + list.next] + + ; if prev + test r11, r11 + jz .no_prev + ; prev->next = cur->next + mov [r11 + list.next], r10 + + jmp .end_if_prev + ;else (no prev) +.no_prev: + ; *begin_list = cur->next + mov [rdi], r10 + +.end_if_prev: + mov r8, r10 + + test rcx, rcx + jnz .free_p +.free: + + push rdi ; begin_list + push r8 ; cur + push r11 ; prev + push rdx ; cmp + push rcx ; free_fct + push rsi ; data_ref + + mov rdi, r9 + call free wrt ..plt + + pop rsi ; data_ref + pop rcx ;free_fct + pop rdx ; cmp + pop r11 ; prev + pop r8 ; cur + pop rdi ; begin_list + + jmp .L1 + +.ret: + ret + +.free_p: + + push r9 + push rdi ; begin_list + push r8 ; cur + push r11 ; prev + push rdx ; cmp + push rcx ; free_fct + push rsi ; data_ref + + mov rdi, [rdi + list.data] + call rcx + + pop rsi ; data_ref + pop rcx ;free_fct + pop rdx ; cmp + pop r11 ; prev + pop r8 ; cur + pop rdi ; begin_list + pop r9 + jmp .free diff --git a/src/libasm.h b/src/libasm.h index a3eb359..cf159a0 100644 --- a/src/libasm.h +++ b/src/libasm.h @@ -24,6 +24,7 @@ int ft_atoibase(char *str, char *base); void ft_list_push_front(t_list **begin_list, void *data); int ft_list_size(t_list *begin_list); void ft_list_sort(t_list **begin_list, int (*cmp)(void *, void *)); +void ft_list_remove_if(t_list **begin_list, void *data_ref, int (*cmp)(void *, void *), void (*free_fct)(void *)); #ifdef __cplusplus }