add ft_list_sort

This commit is contained in:
2025-04-06 01:39:39 +02:00
parent 34b139c60b
commit 919948abe9
11 changed files with 163 additions and 86 deletions

View File

@ -13,7 +13,8 @@ SRCS_NAMES = ft_strlen.s\
SRCS_BONUS_NAMES = ft_atoi_base.s\ SRCS_BONUS_NAMES = ft_atoi_base.s\
ft_list_push_front.s\ ft_list_push_front.s\
ft_list_size.s ft_list_size.s\
ft_list_sort.s
SRCS = $(addprefix $(SRCS_DIR)/, $(SRCS_NAMES)) SRCS = $(addprefix $(SRCS_DIR)/, $(SRCS_NAMES))
SRCS_BONUS = $(addprefix $(SRCS_BONUS_DIR)/, $(SRCS_NAMES)) SRCS_BONUS = $(addprefix $(SRCS_BONUS_DIR)/, $(SRCS_NAMES))

View File

@ -18,5 +18,6 @@ char *ft_strdup(char *src);
int ft_atoi_base(char *nbr, char *base); int ft_atoi_base(char *nbr, 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 *list_start); int ft_list_size(t_list *list_start);
void ft_list_sort(t_list **begin_list, int (*cmp)());
#endif #endif

View File

@ -16,7 +16,7 @@ get_char_index:
get_char_index_loop: get_char_index_loop:
cmp dil, [rsi] ;is char invalid cmp dil, [rsi] ;is char invalid
je get_char_index_found jz get_char_index_found
mov al, [rsi] ; is end of string mov al, [rsi] ; is end of string
test al, al test al, al
@ -40,7 +40,7 @@ check_duplicate_char:
mov al ,[rdi] ; test if \0 mov al ,[rdi] ; test if \0
test al, al test al, al
je no_duplicate jz no_duplicate
push rdi push rdi
mov rsi, rdi mov rsi, rdi
@ -51,7 +51,7 @@ check_duplicate_char:
cmp rax, -1 ;is char found cmp rax, -1 ;is char found
lea rdi, [rdi + 1] lea rdi, [rdi + 1]
je check_duplicate_char jz check_duplicate_char
mov rax, 1 mov rax, 1
ret ret
@ -78,7 +78,7 @@ chk_bs_duplicate:
call check_duplicate_char call check_duplicate_char
pop rdi pop rdi
test rax, rax test rax, rax
je chk_bs_char jz chk_bs_char
xor rax, rax xor rax, rax
ret ret
@ -87,7 +87,7 @@ chk_bs_duplicate:
chk_bs_char: chk_bs_char:
mov al, [rdi] ; if rdi is \0, return 0 mov al, [rdi] ; if rdi is \0, return 0
test al, al test al, al
je base_ok jz base_ok
push rdi ; if current char is in invalid_chars push rdi ; if current char is in invalid_chars
mov dil, [rdi]; mov dil, [rdi];
@ -97,7 +97,7 @@ chk_bs_char:
cmp rax, -1 ; if not -1, error cmp rax, -1 ; if not -1, error
lea rdi, [rdi + 1] lea rdi, [rdi + 1]
je chk_bs_char jz chk_bs_char
xor rax, rax; return 0 xor rax, rax; return 0
ret ret
@ -113,9 +113,9 @@ base_ok:
ft_atoi_base: ft_atoi_base:
xor rax, rax ;check if there is a null pointer in rdi or rsi xor rax, rax ;check if there is a null pointer in rdi or rsi
test rdi, rdi test rdi, rdi
je final_number jz final_number
test rsi, rsi test rsi, rsi
je final_number jz final_number
push rdi ; is base valid push rdi ; is base valid
push rsi push rsi
@ -155,10 +155,10 @@ plus_minus_inc:
plus_minus: plus_minus:
mov al, [rdi] mov al, [rdi]
cmp al, '-' cmp al, '-'
je plus_minus_invert jz plus_minus_invert
cmp al, '+' cmp al, '+'
je plus_minus_inc jz plus_minus_inc
@ -178,7 +178,7 @@ plus_minus:
number_loop: number_loop:
mov dl, [rdi] mov dl, [rdi]
test dl, dl test dl, dl
je final_number jz final_number
push rax push rax
push rdi push rdi
@ -192,7 +192,7 @@ number_loop:
pop rax pop rax
cmp rdx, -1 cmp rdx, -1
je final_number jz final_number
push rdx ; imul sets rdx to 0 push rdx ; imul sets rdx to 0
imul rbx imul rbx

View File

@ -5,7 +5,7 @@ section .text
ft_list_push_front: ft_list_push_front:
test rdi, rdi test rdi, rdi
je err jz err
push rdi push rdi
push rsi push rsi
@ -15,7 +15,7 @@ ft_list_push_front:
pop rdi pop rdi
test rax, rax ; did malloc return 0 test rax, rax ; did malloc return 0
je err jz err
push rdi push rdi
mov rdi, [rdi] mov rdi, [rdi]

View File

@ -7,7 +7,7 @@ ft_list_size:
count_start: count_start:
test rdi, rdi test rdi, rdi
je end jz end
mov rdi, [rdi + 8] mov rdi, [rdi + 8]

84
srcs/bonus/ft_list_sort.s Normal file
View File

@ -0,0 +1,84 @@
global ft_list_sort
extern ft_list_size
section .text
; function that swaps 2 list elements
; takes 2 args :
; - rdi : element 1
; - rsi : element 2
list_swap:
mov rdx, [rdi]
mov rax, [rsi]
mov [rsi], rdx
mov [rdi], rax
ret
ft_list_sort:
test rdi, rdi
jz err
test rsi, rsi
jz err
mov rdi, [rdi]
push rdi
call ft_list_size
pop rdi
loop:
test rax, rax
jz err
push rax
push rdi
push rsi
mov rax, rsi ; move cmp to rax
jmp loop2
loop2_inc:
mov rdi, [rdi + 8]
loop2:
test rdi, rdi
jz loop2_end
mov rsi, [rdi + 8]
test rsi, rsi
jz loop2_end
push rdi
mov rdi, [rdi]
mov rsi, [rsi]
; first call cmp in rax
push rax
call rax
cmp eax, 0
pop rax
pop rdi
jle loop2_inc
; then call list_swap
mov rsi, [rdi + 8]
push rax
call list_swap
pop rax
jmp loop2_inc
loop2_end:
pop rsi
pop rdi
pop rax
lea rax, [rax - 1]
jmp loop
err:
ret

View File

@ -5,20 +5,20 @@ ft_strcmp:
xor rax, rax xor rax, rax
test rdi, rdi ; test if args are false test rdi, rdi ; test if args are false
je err jz err
test rsi, rsi test rsi, rsi
je err jz err
loop_start: loop_start:
mov al, [rdi] mov al, [rdi]
cmp al, [rsi] cmp al, [rsi]
jne compare jne compare
test al, al ; test if rdi is \0 test al, al ; test if rdi is \0
je compare jz compare
mov al, [rsi] ; test if rsi is \0 mov al, [rsi] ; test if rsi is \0
test al, al test al, al
je compare jz compare
lea rsi, [rsi + 1] lea rsi, [rsi + 1]
lea rdi, [rdi + 1] lea rdi, [rdi + 1]

View File

@ -3,15 +3,15 @@ section .text
ft_strcpy: ft_strcpy:
test rdi, rdi test rdi, rdi
je err jz err
test rsi, rsi test rsi, rsi
je err jz err
push rdi push rdi
jmp loop_start jmp loop_start
condition_check: condition_check:
mov al, [rdi] mov al, [rdi]
test al, al test al, al
je end jz end
loop_start: loop_start:
mov rax, [rsi] mov rax, [rsi]

View File

@ -7,7 +7,7 @@ section .text
ft_strdup: ft_strdup:
test rdi, rdi ; test if arg is NULL test rdi, rdi ; test if arg is NULL
je err jz err
push rdi ;push to use it for the strcpy push rdi ;push to use it for the strcpy
call ft_strlen call ft_strlen
@ -15,7 +15,7 @@ ft_strdup:
call malloc wrt ..plt call malloc wrt ..plt
test rax, rax test rax, rax
je malloc_failed jz malloc_failed
mov rdi, rax mov rdi, rax
pop rsi pop rsi
call ft_strcpy call ft_strcpy

View File

@ -3,7 +3,7 @@ section .text
ft_strlen: ft_strlen:
test rdi, rdi test rdi, rdi
je err jz err
mov rsi, rdi mov rsi, rdi
jmp loop_start jmp loop_start

111
test.c
View File

@ -6,7 +6,7 @@
/* By: tomoron <tomoron@student.42angouleme.fr> +#+ +:+ +#+ */ /* By: tomoron <tomoron@student.42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/29 19:53:58 by tomoron #+# #+# */ /* Created: 2025/03/29 19:53:58 by tomoron #+# #+# */
/* Updated: 2025/04/03 04:52:46 by tomoron ### ########.fr */ /* Updated: 2025/04/06 01:39:26 by tomoron ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -22,7 +22,7 @@
#define FNC_TEST(title, condition)\ #define FNC_TEST(title, condition)\
printf(title":\n");\ printf(title":\n");\
if(condition)\ if(!condition)\
printf("RESULT: "OK);\ printf("RESULT: "OK);\
else\ else\
printf(" RESULT: "KO); printf(" RESULT: "KO);
@ -31,57 +31,44 @@
write(1, title, strlen(title));\ write(1, title, strlen(title));\
write(1, ": ", 2);\ write(1, ": ", 2);\
if(condition)\ if(condition)\
{\
write(1, OK, strlen(OK));\ write(1, OK, strlen(OK));\
passed++;\
}\
else \ else \
{\
write(1, KO, strlen(KO));\ write(1, KO, strlen(KO));\
fail++;\
}
int test_strlen(void) int test_strlen(void)
{ {
int nb_tests; int fail = 0;
int passed;
nb_tests = 3;
passed = 0;
TEST("normal string", ft_strlen("hello") == 5); TEST("normal string", ft_strlen("hello") == 5);
TEST("empty string", ft_strlen("") == 0); TEST("empty string", ft_strlen("") == 0);
TEST("null pointer", ft_strlen(NULL) == 0); TEST("null pointer", ft_strlen(NULL) == 0);
return(nb_tests == passed); return(fail);
} }
int test_strcpy(void) int test_strcpy(void)
{ {
int nb_tests; int fail = 0;
int passed;
char buf[256]; char buf[256];
memset(buf,'a', 255); memset(buf,'a', 255);
buf[255] = 0; buf[255] = 0;
nb_tests = 5;
passed = 0;
TEST("copy normal string", strcmp(ft_strcpy(buf, "hello"),"hello") == 0); TEST("copy normal string", strcmp(ft_strcpy(buf, "hello"),"hello") == 0);
TEST("copy empty string", strcmp(ft_strcpy(buf, ""),"") == 0); TEST("copy empty string", strcmp(ft_strcpy(buf, ""),"") == 0);
TEST("copy to null pointer", ft_strcpy(NULL, "") == 0); TEST("copy to null pointer", ft_strcpy(NULL, "") == 0);
TEST("copy from null pointer", ft_strcpy("", NULL) == 0); TEST("copy from null pointer", ft_strcpy("", NULL) == 0);
TEST("copy from and to null pointer", ft_strcpy(NULL, NULL) == 0); TEST("copy from and to null pointer", ft_strcpy(NULL, NULL) == 0);
return(nb_tests == passed); return(fail);
} }
int test_strcmp(void) int test_strcmp(void)
{ {
int nb_tests; int fail = 0;
int passed;
nb_tests = 5;
passed = 0;
TEST("equal string", ft_strcmp("coucou", "coucou") == 0); TEST("equal string", ft_strcmp("coucou", "coucou") == 0);
TEST("second smaller string", ft_strcmp("coucou", "c") == 1); TEST("second smaller string", ft_strcmp("coucou", "c") == 1);
@ -89,17 +76,13 @@ int test_strcmp(void)
TEST("first null", ft_strcmp(NULL, "coucou") == 0); TEST("first null", ft_strcmp(NULL, "coucou") == 0);
TEST("second null", ft_strcmp("hello", NULL) == 0); TEST("second null", ft_strcmp("hello", NULL) == 0);
return(nb_tests == passed); return(fail);
} }
int test_write(void) int test_write(void)
{ {
int nb_tests; int fail = 0;
int passed;
nb_tests = 5;
passed = 0;
TEST("writing hello and test return value", ft_write(1, "hello ", 6) == 6); TEST("writing hello and test return value", ft_write(1, "hello ", 6) == 6);
errno = 0; errno = 0;
TEST("failed write return value", ft_write(-1, "", 0) == (size_t)-1); TEST("failed write return value", ft_write(-1, "", 0) == (size_t)-1);
@ -108,19 +91,15 @@ int test_write(void)
TEST("call write with null pointer, return value", ft_write(1, NULL, 1) == (size_t)-1); TEST("call write with null pointer, return value", ft_write(1, NULL, 1) == (size_t)-1);
TEST("call write with null pointer, errno", errno == 14); TEST("call write with null pointer, errno", errno == 14);
return(nb_tests == passed); return(fail);
} }
int test_read(void) int test_read(void)
{ {
int nb_tests; int fail = 0;
int passed;
int fd; int fd;
char buf[512]; char buf[512];
nb_tests = 8;
passed = 0;
printf("creating test file to test the read function\n"); printf("creating test file to test the read function\n");
fd = open("test_file.tmp", O_WRONLY | O_CREAT, 0600); fd = open("test_file.tmp", O_WRONLY | O_CREAT, 0600);
write(fd, "patate douce", 12); write(fd, "patate douce", 12);
@ -141,19 +120,15 @@ int test_read(void)
close(fd); close(fd);
unlink("test_file.tmp"); unlink("test_file.tmp");
return(nb_tests == passed); return(fail);
} }
int test_strdup(void) int test_strdup(void)
{ {
int nb_tests; int fail = 0;
int passed;
char *src = "patate douce"; char *src = "patate douce";
char *dest; char *dest;
nb_tests = 4;
passed = 0;
dest = ft_strdup(src); dest = ft_strdup(src);
if(!dest) if(!dest)
@ -171,17 +146,12 @@ int test_strdup(void)
free(dest); free(dest);
TEST("strdup null pointer", ft_strdup(NULL) == NULL); TEST("strdup null pointer", ft_strdup(NULL) == NULL);
return(nb_tests == passed); return(fail);
} }
int test_atoi_base(void) int test_atoi_base(void)
{ {
int nb_tests; int fail = 0;
int passed;
nb_tests = 14;
passed = 0;
TEST("normal number base 10", ft_atoi_base("42", "0123456789") == 42); TEST("normal number base 10", ft_atoi_base("42", "0123456789") == 42);
TEST("normal number base 16", ft_atoi_base("1A4", "0123456789ABCDEF") == 420); TEST("normal number base 16", ft_atoi_base("1A4", "0123456789ABCDEF") == 420);
@ -202,18 +172,14 @@ int test_atoi_base(void)
TEST("non-standard base ordering", ft_atoi_base("123", "9876543210") == 876); TEST("non-standard base ordering", ft_atoi_base("123", "9876543210") == 876);
TEST("base 3", ft_atoi_base("321", "123") == 21); TEST("base 3", ft_atoi_base("321", "123") == 21);
return(nb_tests == passed); return(fail);
} }
int test_list_push_front() int test_list_push_front()
{ {
int nb_tests; int fail = 0;
int passed;
t_list *tmp; t_list *tmp;
nb_tests = 4;
passed = 0;
tmp = (void *)0x321; tmp = (void *)0x321;
ft_list_push_front(&tmp, (void *)0x123); ft_list_push_front(&tmp, (void *)0x123);
TEST("does it have a different address", tmp != (void *)0x321); TEST("does it have a different address", tmp != (void *)0x321);
@ -224,17 +190,14 @@ int test_list_push_front()
ft_list_push_front(0, 0); ft_list_push_front(0, 0);
TEST("call with null pointer (should not segfault)", 1); TEST("call with null pointer (should not segfault)", 1);
return(nb_tests == passed); return(fail);
} }
int test_list_size() int test_list_size()
{ {
int nb_tests; int fail = 0;
int passed;
t_list *tmp; t_list *tmp;
nb_tests = 2;
passed = 0;
tmp = 0; tmp = 0;
ft_list_push_front(&tmp, (void *)0x123); ft_list_push_front(&tmp, (void *)0x123);
@ -248,9 +211,33 @@ int test_list_size()
free(tmp->next); free(tmp->next);
free(tmp); free(tmp);
return(nb_tests == passed); return(fail);
} }
int test_list_sort()
{
int fail = 0;
t_list *tmp;
tmp = 0;
ft_list_push_front(&tmp, "d");
ft_list_push_front(&tmp, "a");
ft_list_push_front(&tmp, "b");
ft_list_push_front(&tmp, "c");
ft_list_sort(&tmp, strcmp);
TEST("is list ordered 1", (*(char *)tmp->data) == 'a');
TEST("is list ordered 2", (*(char *)tmp->next->data) == 'b');
TEST("is list ordered 3", (*(char *)tmp->next->next->data) == 'c');
TEST("is list ordered 4", (*(char *)tmp->next->next->next->data) == 'd');
ft_list_sort(0, 0);
TEST("null pointer (should not segfault)", 1);
return(fail);
}
int main(void) int main(void)
{ {
FNC_TEST("ft_strlen", test_strlen()); FNC_TEST("ft_strlen", test_strlen());
@ -270,4 +257,8 @@ int main(void)
FNC_TEST("list_push_front", test_list_push_front()); FNC_TEST("list_push_front", test_list_push_front());
printf("\n\n"); printf("\n\n");
FNC_TEST("list_size", test_list_size()); FNC_TEST("list_size", test_list_size());
printf("\n\n");
FNC_TEST("ft_list_sort", test_list_sort());
printf("\n\n");
FNC_TEST("check valgrind", 1);
} }