add other basic functions and test with them
This commit is contained in:
BIN
.objs/ft_read.o
Normal file
BIN
.objs/ft_read.o
Normal file
Binary file not shown.
BIN
.objs/ft_strcmp.o
Normal file
BIN
.objs/ft_strcmp.o
Normal file
Binary file not shown.
BIN
.objs/ft_strcpy.o
Normal file
BIN
.objs/ft_strcpy.o
Normal file
Binary file not shown.
BIN
.objs/ft_strdup.o
Normal file
BIN
.objs/ft_strdup.o
Normal file
Binary file not shown.
BIN
.objs/ft_strlen.o
Normal file
BIN
.objs/ft_strlen.o
Normal file
Binary file not shown.
BIN
.objs/ft_write.o
Normal file
BIN
.objs/ft_write.o
Normal file
Binary file not shown.
2
Makefile
2
Makefile
@ -19,7 +19,7 @@ FLAGS = -felf64
|
|||||||
all: $(NAME)
|
all: $(NAME)
|
||||||
|
|
||||||
test: test.c $(NAME)
|
test: test.c $(NAME)
|
||||||
clang -z noexecstack test.c $(NAME) -o test
|
clang -z noexecstack test.c -L. -lasm -o test -g
|
||||||
|
|
||||||
$(NAME): $(OBJS_DIR) $(OBJS)
|
$(NAME): $(OBJS_DIR) $(OBJS)
|
||||||
ar rcs $@ $(OBJS)
|
ar rcs $@ $(OBJS)
|
||||||
|
7
patate.c
Normal file
7
patate.c
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
printf("%d\n", strcmp("coucou", "c"));
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
global ft_read
|
||||||
|
extern __errno_location
|
||||||
|
section .text
|
||||||
|
|
||||||
|
ft_read:
|
||||||
|
mov rax, 0 ;syscall number for read, args are already set at the right place
|
||||||
|
syscall
|
||||||
|
|
||||||
|
cmp rax, 0 ; if return is < 0, it's an error in negative
|
||||||
|
jg success
|
||||||
|
|
||||||
|
neg rax ; inv errno, and set errno
|
||||||
|
mov edi, eax
|
||||||
|
call __errno_location wrt ..plt
|
||||||
|
mov [rax], edi
|
||||||
|
mov rax, -1
|
||||||
|
|
||||||
|
success:
|
||||||
|
ret
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
section .text
|
||||||
|
global ft_strcmp
|
||||||
|
|
||||||
|
ft_strcmp:
|
||||||
|
xor rax, rax
|
||||||
|
|
||||||
|
test rdi, rdi ; test if args are false
|
||||||
|
je err
|
||||||
|
test rsi, rsi
|
||||||
|
je err
|
||||||
|
loop_start:
|
||||||
|
mov al, [rdi]
|
||||||
|
cmp al, [rsi]
|
||||||
|
jne compare
|
||||||
|
|
||||||
|
test al, al ; test if rdi is \0
|
||||||
|
je compare
|
||||||
|
|
||||||
|
mov al, [rsi] ; test if rsi is \0
|
||||||
|
test al, al
|
||||||
|
je compare
|
||||||
|
|
||||||
|
lea rsi, [rsi + 1]
|
||||||
|
lea rdi, [rdi + 1]
|
||||||
|
jmp loop_start
|
||||||
|
|
||||||
|
|
||||||
|
compare:
|
||||||
|
mov al, [rdi]
|
||||||
|
cmp al, [rsi]
|
||||||
|
jl lower
|
||||||
|
jg greater
|
||||||
|
mov eax, 0
|
||||||
|
jmp end
|
||||||
|
|
||||||
|
lower:
|
||||||
|
mov eax, -1
|
||||||
|
jmp end
|
||||||
|
|
||||||
|
greater:
|
||||||
|
mov eax, 1
|
||||||
|
jmp end
|
||||||
|
|
||||||
|
err:
|
||||||
|
mov eax, 0
|
||||||
|
|
||||||
|
end:
|
||||||
|
ret
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
section .text
|
||||||
|
global ft_strcpy
|
||||||
|
|
||||||
|
ft_strcpy:
|
||||||
|
test rdi, rdi
|
||||||
|
je err
|
||||||
|
test rsi, rsi
|
||||||
|
je err
|
||||||
|
push rdi
|
||||||
|
jmp loop_start
|
||||||
|
condition_check:
|
||||||
|
mov al, [rdi]
|
||||||
|
test al, al
|
||||||
|
je end
|
||||||
|
|
||||||
|
loop_start:
|
||||||
|
mov rax, [rsi]
|
||||||
|
mov [rdi], rax
|
||||||
|
lea rdi, [rdi + 1]
|
||||||
|
lea rsi, [rsi + 1]
|
||||||
|
jmp condition_check
|
||||||
|
|
||||||
|
end:
|
||||||
|
pop rax
|
||||||
|
ret
|
||||||
|
|
||||||
|
err:
|
||||||
|
xor rax, rax
|
||||||
|
ret
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
extern malloc
|
||||||
|
global ft_strdup
|
||||||
|
extern ft_strcpy
|
||||||
|
extern ft_strlen
|
||||||
|
extern __errno_location
|
||||||
|
section .text
|
||||||
|
|
||||||
|
ft_strdup:
|
||||||
|
test rdi, rdi ; test if arg is NULL
|
||||||
|
je err
|
||||||
|
|
||||||
|
push rdi ;push to use it for the strcpy
|
||||||
|
call ft_strlen
|
||||||
|
mov rdi, rax
|
||||||
|
|
||||||
|
call malloc wrt ..plt
|
||||||
|
test rax, rax
|
||||||
|
je malloc_failed
|
||||||
|
mov rdi, rax
|
||||||
|
pop rsi
|
||||||
|
call ft_strcpy
|
||||||
|
ret
|
||||||
|
|
||||||
|
malloc_failed:
|
||||||
|
call __errno_location wrt ..plt
|
||||||
|
mov dword [rax], 12
|
||||||
|
pop rax
|
||||||
|
|
||||||
|
err:
|
||||||
|
xor rax, rax
|
||||||
|
ret
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
global ft_write
|
||||||
|
extern __errno_location
|
||||||
|
section .text
|
||||||
|
|
||||||
|
ft_write:
|
||||||
|
mov rax, 1 ;syscall number for write, args are already set at the right place
|
||||||
|
syscall
|
||||||
|
|
||||||
|
cmp rax, 0 ; if return is < 0, it's an error in negative
|
||||||
|
jg success
|
||||||
|
|
||||||
|
neg rax ; inv errno, and set errno
|
||||||
|
mov edi, eax
|
||||||
|
call __errno_location wrt ..plt
|
||||||
|
mov [rax], edi
|
||||||
|
mov rax, -1
|
||||||
|
|
||||||
|
|
||||||
|
success:
|
||||||
|
ret
|
||||||
|
158
test.c
158
test.c
@ -1,27 +1,49 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* test.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: tomoron <tomoron@student.42angouleme.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2025/03/29 19:53:58 by tomoron #+# #+# */
|
||||||
|
/* Updated: 2025/03/29 19:54:24 by tomoron ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#define OK "\033[32mOK\n\033[0m"
|
#define OK "\033[32mOK\n\033[0m"
|
||||||
#define KO "\033[31mKO\n\033[0m"
|
#define KO "\033[31mKO\n\033[0m"
|
||||||
|
|
||||||
#define FNC_TEST(title, condition)\
|
#define FNC_TEST(title, condition)\
|
||||||
printf(title":\n");\
|
printf(title":\n");\
|
||||||
if(test_strlen())\
|
if(condition)\
|
||||||
printf("RESULT: "OK);\
|
printf("RESULT: "OK);\
|
||||||
else\
|
else\
|
||||||
printf(" RESULT: "KO);
|
printf(" RESULT: "KO);
|
||||||
|
|
||||||
#define TEST(title, condition) \
|
#define TEST(title, condition) \
|
||||||
printf("%s: ", title);\
|
write(1, title, strlen(title));\
|
||||||
|
write(1, ": ", 2);\
|
||||||
if(condition)\
|
if(condition)\
|
||||||
{\
|
{\
|
||||||
printf(OK);\
|
write(1, OK, strlen(OK));\
|
||||||
passed++;\
|
passed++;\
|
||||||
}\
|
}\
|
||||||
else \
|
else \
|
||||||
printf(KO);
|
write(1, KO, strlen(KO));\
|
||||||
|
|
||||||
size_t ft_strlen(char *str);
|
size_t ft_strlen(char *str);
|
||||||
|
char *ft_strcpy(char *dest, char *src);
|
||||||
|
int ft_strcmp(char *dest, char *src);
|
||||||
|
ssize_t ft_write(int fd, const void *buffer, size_t count);
|
||||||
|
ssize_t ft_read(int fd, void *buffer, size_t count);
|
||||||
|
char *ft_strdup(char *src);
|
||||||
|
|
||||||
int test_strlen(void)
|
int test_strlen(void)
|
||||||
{
|
{
|
||||||
@ -38,8 +60,136 @@ int test_strlen(void)
|
|||||||
return(nb_tests == passed);
|
return(nb_tests == passed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int test_strcpy(void)
|
||||||
|
{
|
||||||
|
int nb_tests;
|
||||||
|
int passed;
|
||||||
|
char buf[256];
|
||||||
|
|
||||||
|
memset(buf,'a', 255);
|
||||||
|
buf[255] = 0;
|
||||||
|
|
||||||
|
nb_tests = 5;
|
||||||
|
passed = 0;
|
||||||
|
|
||||||
|
TEST("copy normal string", strcmp(ft_strcpy(buf, "hello"),"hello") == 0);
|
||||||
|
TEST("copy empty string", strcmp(ft_strcpy(buf, ""),"") == 0);
|
||||||
|
TEST("copy to 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);
|
||||||
|
|
||||||
|
return(nb_tests == passed);
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_strcmp(void)
|
||||||
|
{
|
||||||
|
int nb_tests;
|
||||||
|
int passed;
|
||||||
|
|
||||||
|
nb_tests = 5;
|
||||||
|
passed = 0;
|
||||||
|
|
||||||
|
TEST("equal string", ft_strcmp("coucou", "coucou") == 0);
|
||||||
|
TEST("second smaller string", ft_strcmp("coucou", "c") == 1);
|
||||||
|
TEST("first smaller string", ft_strcmp("c", "coucou") == -1);
|
||||||
|
TEST("first null", ft_strcmp(NULL, "coucou") == 0);
|
||||||
|
TEST("second null", ft_strcmp("hello", NULL) == 0);
|
||||||
|
|
||||||
|
return(nb_tests == passed);
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_write(void)
|
||||||
|
{
|
||||||
|
int nb_tests;
|
||||||
|
int passed;
|
||||||
|
|
||||||
|
nb_tests = 5;
|
||||||
|
passed = 0;
|
||||||
|
|
||||||
|
TEST("writing hello and test return value", ft_write(1, "hello ", 6) == 6);
|
||||||
|
errno = 0;
|
||||||
|
TEST("failed write return value", ft_write(-1, "", 0) == (size_t)-1);
|
||||||
|
TEST("failed write errno test", errno == 9);
|
||||||
|
errno = 0;
|
||||||
|
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);
|
||||||
|
|
||||||
|
return(nb_tests == passed);
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_read(void)
|
||||||
|
{
|
||||||
|
int nb_tests;
|
||||||
|
int passed;
|
||||||
|
int fd;
|
||||||
|
char buf[512];
|
||||||
|
|
||||||
|
nb_tests = 8;
|
||||||
|
passed = 0;
|
||||||
|
|
||||||
|
printf("creating test file to test the read function\n");
|
||||||
|
fd = open("test_file.tmp", O_WRONLY | O_CREAT, 0600);
|
||||||
|
write(fd, "patate douce", 12);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
fd = open("test_file.tmp", O_RDONLY);
|
||||||
|
TEST("read 1 char", ft_read(fd, buf, 1) == 1);
|
||||||
|
TEST("check read char", memcmp(buf, "p", 1) == 0);
|
||||||
|
TEST("read multiple char", ft_read(fd, buf, 5) == 5);
|
||||||
|
TEST("compare with expected", memcmp(buf, "atate", 5) == 0);
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
TEST("invalid fd read, return", ft_read(-1, buf, 20) == (size_t)-1);
|
||||||
|
TEST("invalid fd read, errno", errno == 9);
|
||||||
|
errno = 0;
|
||||||
|
TEST("read to null pointer, return", ft_read(fd, NULL, 4) == (size_t)-1)
|
||||||
|
TEST("read to null pointer, errno", errno == 14)
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return(nb_tests == passed);
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_strdup(void)
|
||||||
|
{
|
||||||
|
int nb_tests;
|
||||||
|
int passed;
|
||||||
|
char *src = "patate douce";
|
||||||
|
char *dest;
|
||||||
|
|
||||||
|
nb_tests = 4;
|
||||||
|
passed = 0;
|
||||||
|
|
||||||
|
dest = ft_strdup(src);
|
||||||
|
|
||||||
|
if(!dest)
|
||||||
|
{
|
||||||
|
printf("strdup failed, probably testing errno, returing with result\n");
|
||||||
|
return(errno == ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST("strdup normal stiring, diff pointer", dest != src);
|
||||||
|
TEST("strdup normal string , content", !strcmp(dest, src));
|
||||||
|
free(dest);
|
||||||
|
|
||||||
|
dest = ft_strdup("");
|
||||||
|
TEST("strdup empty string", *dest == 0);
|
||||||
|
free(dest);
|
||||||
|
TEST("strdup null pointer", ft_strdup(NULL) == NULL);
|
||||||
|
|
||||||
|
return(nb_tests == passed);
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
FNC_TEST("ft_strlen", test_strlen());
|
FNC_TEST("ft_strlen", test_strlen());
|
||||||
printf("\n\n");
|
printf("\n\n");
|
||||||
|
FNC_TEST("ft_strcpy", test_strcpy());
|
||||||
|
printf("\n\n");
|
||||||
|
FNC_TEST("ft_strcmp", test_strcmp());
|
||||||
|
printf("\n\n");
|
||||||
|
FNC_TEST("ft_write", test_write());
|
||||||
|
printf("\n\n");
|
||||||
|
FNC_TEST("ft_read", test_read());
|
||||||
|
printf("\n\n");
|
||||||
|
FNC_TEST("ft_strdup", test_strdup());
|
||||||
}
|
}
|
||||||
|
1
test_file.tmp
Normal file
1
test_file.tmp
Normal file
@ -0,0 +1 @@
|
|||||||
|
patate douce
|
Reference in New Issue
Block a user