feat: ft_list_remove_if

This commit is contained in:
lohhiiccc 2026-06-22 18:18:19 +02:00
parent 25b56f1cd0
commit 79e3fdb620
3 changed files with 174 additions and 1 deletions

View file

@ -22,7 +22,8 @@ SRCS=$(SRC_DIR)/ft_strlen.s \
$(SRC_DIR)/ft_atoibase.s \ $(SRC_DIR)/ft_atoibase.s \
$(SRC_DIR)/ft_list_push_front.s \ $(SRC_DIR)/ft_list_push_front.s \
$(SRC_DIR)/ft_list_size.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)) OBJS=$(patsubst $(SRC_DIR)/%.s,$(OBJ_DIR)/%.o,$(SRCS))
DEPS=$(OBJS:.o=.d) DEPS=$(OBJS:.o=.d)

171
src/ft_list_remove_if.s Normal file
View file

@ -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

View file

@ -24,6 +24,7 @@ int ft_atoibase(char *str, char *base);
void ft_list_push_front(t_list **begin_list, void *data); void ft_list_push_front(t_list **begin_list, void *data);
int ft_list_size(t_list *begin_list); int ft_list_size(t_list *begin_list);
void ft_list_sort(t_list **begin_list, int (*cmp)(void *, void *)); 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 #ifdef __cplusplus
} }