finish ft_atoi_base
This commit is contained in:
1
Makefile
1
Makefile
@ -28,6 +28,7 @@ libasm_bonus.a : $(OBJS_DIR) $(OBJS) $(OBJS_BONUS)
|
|||||||
|
|
||||||
test: test.c libasm_bonus.a
|
test: test.c libasm_bonus.a
|
||||||
clang -z noexecstack test.c -L. -lasm_bonus -o test -g
|
clang -z noexecstack test.c -L. -lasm_bonus -o test -g
|
||||||
|
./test || echo -e "\033[31m tests exited with an error code"
|
||||||
|
|
||||||
$(NAME): $(OBJS_DIR) $(OBJS)
|
$(NAME): $(OBJS_DIR) $(OBJS)
|
||||||
ar rcs $@ $(OBJS)
|
ar rcs $@ $(OBJS)
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
; atoi base
|
|
||||||
; prototype : int ft_atoi_base(char *str, char *base)
|
|
||||||
|
|
||||||
;global ft_atoi_base
|
global ft_atoi_base
|
||||||
global get_char_index
|
global check_duplicate_char
|
||||||
global check_base
|
extern ft_strlen
|
||||||
|
|
||||||
section .data
|
section .data
|
||||||
invalid_chars: db "+- ", 0x0c, 0x0a, 0x0d, 0x09, 0x0b, 0
|
invalid_chars: db "+- ", 0x0c, 0x0a, 0x0d, 0x09, 0x0b, 0
|
||||||
|
whitespaces: db " ", 0x0c, 0x0a, 0x0d, 0x09, 0x0b, 0
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
|
|
||||||
@ -24,7 +23,7 @@ get_char_index_loop:
|
|||||||
lea rsi, [rsi + 1]
|
lea rsi, [rsi + 1]
|
||||||
jne get_char_index_loop
|
jne get_char_index_loop
|
||||||
|
|
||||||
xor rax, -1 ;not found and at the end
|
mov rax, -1 ;not found and at the end
|
||||||
pop rsi
|
pop rsi
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -34,12 +33,57 @@ get_char_index_found:
|
|||||||
mov rax, rsi
|
mov rax, rsi
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
;function that ... it's in the name why are you looking here
|
||||||
|
; parameters : the string in rdi
|
||||||
|
; returns 1 if there is a duplicate char
|
||||||
|
check_duplicate_char:
|
||||||
|
|
||||||
|
mov al ,[rdi] ; test if \0
|
||||||
|
test al, al
|
||||||
|
je no_duplicate
|
||||||
|
|
||||||
|
push rdi
|
||||||
|
mov rsi, rdi
|
||||||
|
lea rsi, [rsi + 1]
|
||||||
|
mov dil, [rdi]
|
||||||
|
call get_char_index
|
||||||
|
pop rdi
|
||||||
|
|
||||||
|
cmp rax, -1 ;is char found
|
||||||
|
lea rdi, [rdi + 1]
|
||||||
|
je check_duplicate_char
|
||||||
|
mov rax, 1
|
||||||
|
ret
|
||||||
|
|
||||||
|
no_duplicate:
|
||||||
|
xor rax, rax
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;function that checks if the base is valid
|
;function that checks if the base is valid
|
||||||
;a valid base does not have any of these char : "+-" or any space defined by isspace(3) and does not have any duplicate char
|
;a valid base does not have any of these char : "+-" or any space defined by isspace(3) and does not have any duplicate char or does not have any char
|
||||||
; returns 0 if base is not valid
|
; returns 0 if base is not valid
|
||||||
check_base:
|
check_base:
|
||||||
xor rax, rax
|
xor rax, rax
|
||||||
|
|
||||||
|
mov al, [rdi] ; check if it's an empty string
|
||||||
|
test al, al
|
||||||
|
jne chk_bs_duplicate
|
||||||
|
xor rax, rax
|
||||||
|
ret
|
||||||
|
|
||||||
|
chk_bs_duplicate:
|
||||||
|
push rdi
|
||||||
|
call check_duplicate_char
|
||||||
|
pop rdi
|
||||||
|
test rax, rax
|
||||||
|
je chk_bs_char
|
||||||
|
|
||||||
|
xor rax, rax
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
@ -61,3 +105,110 @@ chk_bs_char:
|
|||||||
base_ok:
|
base_ok:
|
||||||
mov rax,1
|
mov rax,1
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; prototype : int ft_atoi_base(char *str, char *base)
|
||||||
|
; rdi str
|
||||||
|
; rsi base
|
||||||
|
ft_atoi_base:
|
||||||
|
xor rax, rax ;check if there is a null pointer in rdi or rsi
|
||||||
|
test rdi, rdi
|
||||||
|
je final_number
|
||||||
|
test rsi, rsi
|
||||||
|
je final_number
|
||||||
|
|
||||||
|
push rdi ; is base valid
|
||||||
|
push rsi
|
||||||
|
mov rdi, rsi
|
||||||
|
call check_base
|
||||||
|
pop rsi
|
||||||
|
pop rdi
|
||||||
|
|
||||||
|
test rax, rax
|
||||||
|
jne whitespace_skip ; if 0 , base is not valid
|
||||||
|
xor rax, rax
|
||||||
|
ret
|
||||||
|
|
||||||
|
xor rdx, rdx
|
||||||
|
|
||||||
|
whitespace_skip_inc:
|
||||||
|
lea rdi, [rdi + 1]
|
||||||
|
whitespace_skip:
|
||||||
|
push rdi
|
||||||
|
push rsi
|
||||||
|
mov dil, [rdi]
|
||||||
|
lea rsi, [rel whitespaces]
|
||||||
|
call get_char_index
|
||||||
|
pop rsi
|
||||||
|
pop rdi
|
||||||
|
|
||||||
|
cmp rax, 0
|
||||||
|
jge whitespace_skip_inc
|
||||||
|
jmp plus_minus
|
||||||
|
|
||||||
|
plus_minus_invert:
|
||||||
|
xor rdx, 1
|
||||||
|
|
||||||
|
plus_minus_inc:
|
||||||
|
lea rdi, [rdi + 1]
|
||||||
|
|
||||||
|
plus_minus:
|
||||||
|
mov al, [rdi]
|
||||||
|
cmp al, '-'
|
||||||
|
je plus_minus_invert
|
||||||
|
|
||||||
|
cmp al, '+'
|
||||||
|
je plus_minus_inc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
push rdi
|
||||||
|
push rsi
|
||||||
|
mov rdi, rsi
|
||||||
|
call ft_strlen
|
||||||
|
pop rsi
|
||||||
|
pop rdi
|
||||||
|
|
||||||
|
mov rbx, rax
|
||||||
|
|
||||||
|
xor rax, rax
|
||||||
|
|
||||||
|
push rdx
|
||||||
|
|
||||||
|
number_loop:
|
||||||
|
mov dl, [rdi]
|
||||||
|
test dl, dl
|
||||||
|
je final_number
|
||||||
|
|
||||||
|
push rax
|
||||||
|
push rdi
|
||||||
|
push rsi
|
||||||
|
mov dil, dl
|
||||||
|
call get_char_index
|
||||||
|
pop rsi
|
||||||
|
pop rdi
|
||||||
|
|
||||||
|
mov rdx, rax ; save return value in rdx
|
||||||
|
pop rax
|
||||||
|
|
||||||
|
cmp rdx, -1
|
||||||
|
je final_number
|
||||||
|
|
||||||
|
push rdx ; imul sets rdx to 0
|
||||||
|
imul rbx
|
||||||
|
pop rdx
|
||||||
|
add rax, rdx
|
||||||
|
|
||||||
|
lea rdi, [rdi + 1]
|
||||||
|
|
||||||
|
jmp number_loop
|
||||||
|
|
||||||
|
final_number:
|
||||||
|
pop rdx
|
||||||
|
test rdx, rdx
|
||||||
|
jne neg_final_number
|
||||||
|
ret
|
||||||
|
|
||||||
|
neg_final_number:
|
||||||
|
neg rax
|
||||||
|
ret
|
||||||
|
31
test.c
31
test.c
@ -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/03/31 16:42:55 by tomoron ### ########.fr */
|
/* Updated: 2025/04/02 02:35:57 by tomoron ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -44,6 +44,7 @@ int ft_strcmp(char *dest, char *src);
|
|||||||
ssize_t ft_write(int fd, const void *buffer, size_t count);
|
ssize_t ft_write(int fd, const void *buffer, size_t count);
|
||||||
ssize_t ft_read(int fd, void *buffer, size_t count);
|
ssize_t ft_read(int fd, void *buffer, size_t count);
|
||||||
char *ft_strdup(char *src);
|
char *ft_strdup(char *src);
|
||||||
|
int ft_atoi_base(char *nbr, char *base);
|
||||||
|
|
||||||
int test_strlen(void)
|
int test_strlen(void)
|
||||||
{
|
{
|
||||||
@ -180,17 +181,33 @@ int test_strdup(void)
|
|||||||
return(nb_tests == passed);
|
return(nb_tests == passed);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t check_base(char *base);
|
int test_atoi_base(void)
|
||||||
int tmp(void)
|
|
||||||
{
|
{
|
||||||
int nb_tests;
|
int nb_tests;
|
||||||
int passed;
|
int passed;
|
||||||
|
|
||||||
nb_tests = 4;
|
nb_tests = 14;
|
||||||
passed = 0;
|
passed = 0;
|
||||||
|
|
||||||
TEST("a", check_base("a") == 1);
|
|
||||||
TEST("a", check_base("abcdef") == 1);
|
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 2", ft_atoi_base("101", "01") == 5);
|
||||||
|
|
||||||
|
TEST("0", ft_atoi_base("0", "0123456789") == 0);
|
||||||
|
TEST("leading zeros", ft_atoi_base("0001", "0123456789") == 1);
|
||||||
|
TEST("max 16-bit hex", ft_atoi_base("FFFF", "0123456789ABCDEF") == 65535);
|
||||||
|
|
||||||
|
TEST("empty number", ft_atoi_base("", "0123456789") == 0);
|
||||||
|
TEST("empty base", ft_atoi_base("123", "") == 0);
|
||||||
|
TEST("invalid digit in base", ft_atoi_base("42abc", "0123456789") == 42);
|
||||||
|
TEST("duplicate characters in base", ft_atoi_base("123", "01234566789") == 0);
|
||||||
|
|
||||||
|
TEST("large number within int range", ft_atoi_base("2147483647", "0123456789") == 2147483647);
|
||||||
|
TEST("negative number", ft_atoi_base("-42", "0123456789") == -42);
|
||||||
|
|
||||||
|
TEST("non-standard base ordering", ft_atoi_base("123", "9876543210") == 876);
|
||||||
|
TEST("base 3", ft_atoi_base("321", "123") == 21);
|
||||||
|
|
||||||
return(nb_tests == passed);
|
return(nb_tests == passed);
|
||||||
}
|
}
|
||||||
@ -209,5 +226,5 @@ int main(void)
|
|||||||
printf("\n\n");
|
printf("\n\n");
|
||||||
FNC_TEST("ft_strdup", test_strdup());
|
FNC_TEST("ft_strdup", test_strdup());
|
||||||
printf("\n\n");
|
printf("\n\n");
|
||||||
FNC_TEST("tmp", tmp());
|
FNC_TEST("atoi_base", test_atoi_base());
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user