diff --git a/.gitignore b/.gitignore index a9b1dd5..14b2bca 100644 --- a/.gitignore +++ b/.gitignore @@ -54,7 +54,7 @@ dkms.conf ./generic .direnv test -output/ +# /output/ push_swap push_swap_visualizer Push-Swap-Tester diff --git a/output/include/me/vec/vec_i64.h b/output/include/me/vec/vec_i64.h new file mode 100644 index 0000000..8a8f200 --- /dev/null +++ b/output/include/me/vec/vec_i64.h @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_i64.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/04 18:46:53 by maiboyer #+# #+# */ +/* Updated: 2023/12/09 17:53:00 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef VEC_I64_H +# define VEC_I64_H + +# include "me/types.h" + +typedef bool (*t_vec_i64_sort_fn)(t_i64 *, t_i64 *); +typedef void (*t_free_i64_item)(t_i64); + +typedef struct s_vec_i64 +{ + t_free_i64_item free_func; + t_usize len; + t_usize capacity; + t_i64 *buffer; +} t_vec_i64; + +t_vec_i64 vec_i64_new(t_usize capacity, + t_free_i64_item free_function); +t_error vec_i64_push(t_vec_i64 *vec, t_i64 element); +t_error vec_i64_push_front(t_vec_i64 *vec, t_i64 element); +t_error vec_i64_pop(t_vec_i64 *vec, t_i64 *value); +t_error vec_i64_pop_front(t_vec_i64 *vec, t_i64 *value); +void vec_i64_free(t_vec_i64 vec); +t_error vec_i64_reserve(t_vec_i64 *vec, t_usize wanted_capacity); +t_error vec_i64_find(t_vec_i64 *vec, bool (*fn)(const t_i64 *), + t_usize *index); +t_error vec_i64_find_starting(t_vec_i64 *vec, + bool (*fn)(const t_i64 *), t_usize starting_index, + t_usize *index); +t_error vec_i64_all(t_vec_i64 *vec, bool (*fn)(const t_i64 *), + bool *result); +t_error vec_i64_any(t_vec_i64 *vec, bool (*fn)(const t_i64 *), + bool *result); +void vec_i64_iter(t_vec_i64 *vec, void (*fn)(t_usize index, + t_i64 *value, void *state), void *state); +void vec_i64_reverse(t_vec_i64 *vec); +void vec_i64_sort(t_vec_i64 *vec, t_vec_i64_sort_fn is_sorted); + +#endif diff --git a/output/include/me/vec/vec_i64_bool.h b/output/include/me/vec/vec_i64_bool.h new file mode 100644 index 0000000..42f456a --- /dev/null +++ b/output/include/me/vec/vec_i64_bool.h @@ -0,0 +1,60 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_i64_bool.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/04 18:46:53 by maiboyer #+# #+# */ +/* Updated: 2023/12/09 17:53:00 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef VEC_I64_BOOL_H +# define VEC_I64_BOOL_H + +# include "app/types/type_i64_bool.h" +# include "me/types.h" + +typedef bool (*t_vec_i64_bool_sort_fn)(t_i64_bool *, + t_i64_bool *); +typedef void (*t_free_i64_bool_item)(t_i64_bool); + +typedef struct s_vec_i64_bool +{ + t_free_i64_bool_item free_func; + t_usize len; + t_usize capacity; + t_i64_bool *buffer; +} t_vec_i64_bool; + +t_vec_i64_bool vec_i64_bool_new(t_usize capacity, + t_free_i64_bool_item free_function); +t_error vec_i64_bool_push(t_vec_i64_bool *vec, + t_i64_bool element); +t_error vec_i64_bool_push_front(t_vec_i64_bool *vec, + t_i64_bool element); +t_error vec_i64_bool_pop(t_vec_i64_bool *vec, + t_i64_bool *value); +t_error vec_i64_bool_pop_front(t_vec_i64_bool *vec, + t_i64_bool *value); +void vec_i64_bool_free(t_vec_i64_bool vec); +t_error vec_i64_bool_reserve(t_vec_i64_bool *vec, + t_usize wanted_capacity); +t_error vec_i64_bool_find(t_vec_i64_bool *vec, + bool (*fn)(const t_i64_bool *), t_usize *index); +t_error vec_i64_bool_find_starting(t_vec_i64_bool *vec, + bool (*fn)(const t_i64_bool *), + t_usize starting_index, t_usize *index); +t_error vec_i64_bool_all(t_vec_i64_bool *vec, + bool (*fn)(const t_i64_bool *), bool *result); +t_error vec_i64_bool_any(t_vec_i64_bool *vec, + bool (*fn)(const t_i64_bool *), bool *result); +void vec_i64_bool_iter(t_vec_i64_bool *vec, + void (*fn)(t_usize index, t_i64_bool *value, + void *state), void *state); +void vec_i64_bool_reverse(t_vec_i64_bool *vec); +void vec_i64_bool_sort(t_vec_i64_bool *vec, + t_vec_i64_bool_sort_fn is_sorted); + +#endif diff --git a/output/src/convert/str_to_i16.c b/output/src/convert/str_to_i16.c new file mode 100644 index 0000000..b1d2bc8 --- /dev/null +++ b/output/src/convert/str_to_i16.c @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/string/str_len.h" +#include "me/types.h" + +#define OP_ADD 0b0001 +#define OP_SUB 0b0010 +#define OP_MUL 0b0100 +#define OP_CHK 0b1000 + +t_error checked_add_i16(t_i16 lhs, t_i16 rhs, t_i16 *out); +t_error checked_sub_i16(t_i16 lhs, t_i16 rhs, t_i16 *out); +t_error checked_mul_i16(t_i16 lhs, t_i16 rhs, t_i16 *out); + +static inline bool can_not_overflow(t_u32 radix, bool is_signed_type, + t_usize digits_len) +{ + return (radix <= 16 && digits_len <= sizeof(t_i16) * 2 + - (t_usize)is_signed_type); +} + +static inline t_error to_digit(t_u8 ascii, t_u32 radix, t_u32 *out) +{ + t_u32 digit; + + if (radix < 2 || radix > 36) + return (ERROR); + digit = ascii - '0'; + if (radix > 10 && digit >= 10) + { + if (!me_isalpha(ascii)) + return (ERROR); + digit = ((ascii | 0b100000) - 'a') + 10; + } + if (digit >= radix) + return (ERROR); + *out = digit; + return (NO_ERROR); +} + +static inline t_error do_operation(t_i16 digit, t_u8 op, t_i16 *result) +{ + t_i16 rhs; + t_i16 res; + + rhs = *result; + res = *result; + if (op & OP_CHK) + { + if (op & OP_MUL && checked_mul_i16(rhs, digit, &res)) + return (ERROR); + else if (op & OP_ADD && checked_add_i16(rhs, digit, &res)) + return (ERROR); + else if (op & OP_SUB && checked_sub_i16(rhs, digit, &res)) + return (ERROR); + } + else + { + if (op & OP_MUL) + res = rhs * digit; + else if (op & OP_ADD) + res = rhs + digit; + else if (op & OP_SUB) + res = rhs - digit; + } + *result = res; + return (NO_ERROR); +} + +static inline t_error loop_inner(t_const_str s, t_u32 radix, t_u8 op, + t_i16 *out) +{ + t_u32 digit; + t_i16 result; + + result = 0; + while (*s) + { + if (do_operation(radix, (op & OP_CHK) | OP_MUL, &result)) + return (ERROR); + if (to_digit(*s, radix, &digit)) + return (ERROR); + if (do_operation(digit, op, &result)) + return (ERROR); + s++; + } + if (out) + *out = result; + return (NO_ERROR); +} + +t_error str_to_i16(t_const_str s, t_u32 radix, t_i16 *out) +{ + t_usize digits_len; + bool is_positive; + t_u8 op; + + if (radix < 2 || radix > 36) + return (ERROR); + digits_len = str_len(s); + is_positive = true; + if (digits_len == 0) + return (ERROR); + if ((s[0] == '-' || s[0] == '+') && s[1] == '\0') + return (ERROR); + else if (s[0] == '+') + is_positive = (s++, digits_len--, true); + else if (s[0] == '-' && true) + is_positive = (s++, digits_len--, false); + if (is_positive) + op = OP_ADD; + else + op = OP_SUB; + if (!can_not_overflow(radix, true, digits_len)) + op |= OP_CHK; + return (loop_inner(s, radix, op, out)); +} diff --git a/output/src/convert/str_to_i16_utils.c b/output/src/convert/str_to_i16_utils.c new file mode 100644 index 0000000..4ecbbe2 --- /dev/null +++ b/output/src/convert/str_to_i16_utils.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i16_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 18:55:47 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/printf/printf.h" +#include "me/string/str_len.h" +#include "me/types.h" + +t_error checked_add_i16(t_i16 lhs, t_i16 rhs, t_i16 *out) +{ + if (rhs > 0 && (lhs > 32767 - rhs)) + return (ERROR); + *out = (t_i16)(lhs + rhs); + return (NO_ERROR); +} + +t_error checked_sub_i16(t_i16 lhs, t_i16 rhs, t_i16 *out) +{ + if ((((rhs & (1 << (sizeof(t_i16) - 1)) || rhs == 0) || !true) && (lhs < \ + -32768 + rhs))) + return (ERROR); + *out = (t_i16)(lhs - rhs); + return (NO_ERROR); +} + +t_error checked_mul_i16(t_i16 lhs, t_i16 rhs, t_i16 *out) +{ + t_i16 mul; + + mul = lhs * rhs; + if (lhs != 0 && mul / lhs != rhs) + return (ERROR); + *out = mul; + return (NO_ERROR); +} diff --git a/output/src/convert/str_to_i32.c b/output/src/convert/str_to_i32.c new file mode 100644 index 0000000..4956029 --- /dev/null +++ b/output/src/convert/str_to_i32.c @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/string/str_len.h" +#include "me/types.h" + +#define OP_ADD 0b0001 +#define OP_SUB 0b0010 +#define OP_MUL 0b0100 +#define OP_CHK 0b1000 + +t_error checked_add_i32(t_i32 lhs, t_i32 rhs, t_i32 *out); +t_error checked_sub_i32(t_i32 lhs, t_i32 rhs, t_i32 *out); +t_error checked_mul_i32(t_i32 lhs, t_i32 rhs, t_i32 *out); + +static inline bool can_not_overflow(t_u32 radix, bool is_signed_type, + t_usize digits_len) +{ + return (radix <= 16 && digits_len <= sizeof(t_i32) * 2 + - (t_usize)is_signed_type); +} + +static inline t_error to_digit(t_u8 ascii, t_u32 radix, t_u32 *out) +{ + t_u32 digit; + + if (radix < 2 || radix > 36) + return (ERROR); + digit = ascii - '0'; + if (radix > 10 && digit >= 10) + { + if (!me_isalpha(ascii)) + return (ERROR); + digit = ((ascii | 0b100000) - 'a') + 10; + } + if (digit >= radix) + return (ERROR); + *out = digit; + return (NO_ERROR); +} + +static inline t_error do_operation(t_i32 digit, t_u8 op, t_i32 *result) +{ + t_i32 rhs; + t_i32 res; + + rhs = *result; + res = *result; + if (op & OP_CHK) + { + if (op & OP_MUL && checked_mul_i32(rhs, digit, &res)) + return (ERROR); + else if (op & OP_ADD && checked_add_i32(rhs, digit, &res)) + return (ERROR); + else if (op & OP_SUB && checked_sub_i32(rhs, digit, &res)) + return (ERROR); + } + else + { + if (op & OP_MUL) + res = rhs * digit; + else if (op & OP_ADD) + res = rhs + digit; + else if (op & OP_SUB) + res = rhs - digit; + } + *result = res; + return (NO_ERROR); +} + +static inline t_error loop_inner(t_const_str s, t_u32 radix, t_u8 op, + t_i32 *out) +{ + t_u32 digit; + t_i32 result; + + result = 0; + while (*s) + { + if (do_operation(radix, (op & OP_CHK) | OP_MUL, &result)) + return (ERROR); + if (to_digit(*s, radix, &digit)) + return (ERROR); + if (do_operation(digit, op, &result)) + return (ERROR); + s++; + } + if (out) + *out = result; + return (NO_ERROR); +} + +t_error str_to_i32(t_const_str s, t_u32 radix, t_i32 *out) +{ + t_usize digits_len; + bool is_positive; + t_u8 op; + + if (radix < 2 || radix > 36) + return (ERROR); + digits_len = str_len(s); + is_positive = true; + if (digits_len == 0) + return (ERROR); + if ((s[0] == '-' || s[0] == '+') && s[1] == '\0') + return (ERROR); + else if (s[0] == '+') + is_positive = (s++, digits_len--, true); + else if (s[0] == '-' && true) + is_positive = (s++, digits_len--, false); + if (is_positive) + op = OP_ADD; + else + op = OP_SUB; + if (!can_not_overflow(radix, true, digits_len)) + op |= OP_CHK; + return (loop_inner(s, radix, op, out)); +} diff --git a/output/src/convert/str_to_i32_utils.c b/output/src/convert/str_to_i32_utils.c new file mode 100644 index 0000000..5b6f5fd --- /dev/null +++ b/output/src/convert/str_to_i32_utils.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i32_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 18:56:06 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/printf/printf.h" +#include "me/string/str_len.h" +#include "me/types.h" + +t_error checked_add_i32(t_i32 lhs, t_i32 rhs, t_i32 *out) +{ + if (rhs > 0 && (lhs > 2147483647 - rhs)) + return (ERROR); + *out = (t_i32)(lhs + rhs); + return (NO_ERROR); +} + +t_error checked_sub_i32(t_i32 lhs, t_i32 rhs, t_i32 *out) +{ + if ((((rhs & (1 << (sizeof(t_i32) - 1)) || rhs == 0) || !true) && (lhs < \ + -2147483648 + rhs))) + return (ERROR); + *out = (t_i32)(lhs - rhs); + return (NO_ERROR); +} + +t_error checked_mul_i32(t_i32 lhs, t_i32 rhs, t_i32 *out) +{ + t_i32 mul; + + mul = lhs * rhs; + if (lhs != 0 && mul / lhs != rhs) + return (ERROR); + *out = mul; + return (NO_ERROR); +} diff --git a/output/src/convert/str_to_i64.c b/output/src/convert/str_to_i64.c new file mode 100644 index 0000000..56a48cc --- /dev/null +++ b/output/src/convert/str_to_i64.c @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/string/str_len.h" +#include "me/types.h" + +#define OP_ADD 0b0001 +#define OP_SUB 0b0010 +#define OP_MUL 0b0100 +#define OP_CHK 0b1000 + +t_error checked_add_i64(t_i64 lhs, t_i64 rhs, t_i64 *out); +t_error checked_sub_i64(t_i64 lhs, t_i64 rhs, t_i64 *out); +t_error checked_mul_i64(t_i64 lhs, t_i64 rhs, t_i64 *out); + +static inline bool can_not_overflow(t_u32 radix, bool is_signed_type, + t_usize digits_len) +{ + return (radix <= 16 && digits_len <= sizeof(t_i64) * 2 + - (t_usize)is_signed_type); +} + +static inline t_error to_digit(t_u8 ascii, t_u32 radix, t_u32 *out) +{ + t_u32 digit; + + if (radix < 2 || radix > 36) + return (ERROR); + digit = ascii - '0'; + if (radix > 10 && digit >= 10) + { + if (!me_isalpha(ascii)) + return (ERROR); + digit = ((ascii | 0b100000) - 'a') + 10; + } + if (digit >= radix) + return (ERROR); + *out = digit; + return (NO_ERROR); +} + +static inline t_error do_operation(t_i64 digit, t_u8 op, t_i64 *result) +{ + t_i64 rhs; + t_i64 res; + + rhs = *result; + res = *result; + if (op & OP_CHK) + { + if (op & OP_MUL && checked_mul_i64(rhs, digit, &res)) + return (ERROR); + else if (op & OP_ADD && checked_add_i64(rhs, digit, &res)) + return (ERROR); + else if (op & OP_SUB && checked_sub_i64(rhs, digit, &res)) + return (ERROR); + } + else + { + if (op & OP_MUL) + res = rhs * digit; + else if (op & OP_ADD) + res = rhs + digit; + else if (op & OP_SUB) + res = rhs - digit; + } + *result = res; + return (NO_ERROR); +} + +static inline t_error loop_inner(t_const_str s, t_u32 radix, t_u8 op, + t_i64 *out) +{ + t_u32 digit; + t_i64 result; + + result = 0ll; + while (*s) + { + if (do_operation(radix, (op & OP_CHK) | OP_MUL, &result)) + return (ERROR); + if (to_digit(*s, radix, &digit)) + return (ERROR); + if (do_operation(digit, op, &result)) + return (ERROR); + s++; + } + if (out) + *out = result; + return (NO_ERROR); +} + +t_error str_to_i64(t_const_str s, t_u32 radix, t_i64 *out) +{ + t_usize digits_len; + bool is_positive; + t_u8 op; + + if (radix < 2 || radix > 36) + return (ERROR); + digits_len = str_len(s); + is_positive = true; + if (digits_len == 0) + return (ERROR); + if ((s[0] == '-' || s[0] == '+') && s[1] == '\0') + return (ERROR); + else if (s[0] == '+') + is_positive = (s++, digits_len--, true); + else if (s[0] == '-' && true) + is_positive = (s++, digits_len--, false); + if (is_positive) + op = OP_ADD; + else + op = OP_SUB; + if (!can_not_overflow(radix, true, digits_len)) + op |= OP_CHK; + return (loop_inner(s, radix, op, out)); +} diff --git a/output/src/convert/str_to_i64_utils.c b/output/src/convert/str_to_i64_utils.c new file mode 100644 index 0000000..1dd268d --- /dev/null +++ b/output/src/convert/str_to_i64_utils.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 18:55:37 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/printf/printf.h" +#include "me/string/str_len.h" +#include "me/types.h" + +t_error checked_add_i64(t_i64 lhs, t_i64 rhs, t_i64 *out) +{ + if (rhs > 0 && (lhs > 9223372036854775807ll - rhs)) + return (ERROR); + *out = (t_i64)(lhs + rhs); + return (NO_ERROR); +} + +t_error checked_sub_i64(t_i64 lhs, t_i64 rhs, t_i64 *out) +{ + if ((((rhs & (1 << (sizeof(t_i64) - 1)) || rhs == 0) || !true) && (lhs < \ + -(~9223372036854775807ll + 1) + rhs))) + return (ERROR); + *out = (t_i64)(lhs - rhs); + return (NO_ERROR); +} + +t_error checked_mul_i64(t_i64 lhs, t_i64 rhs, t_i64 *out) +{ + t_i64 mul; + + mul = lhs * rhs; + if (lhs != 0 && mul / lhs != rhs) + return (ERROR); + *out = mul; + return (NO_ERROR); +} diff --git a/output/src/convert/str_to_i8.c b/output/src/convert/str_to_i8.c new file mode 100644 index 0000000..80f91a0 --- /dev/null +++ b/output/src/convert/str_to_i8.c @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/string/str_len.h" +#include "me/types.h" + +#define OP_ADD 0b0001 +#define OP_SUB 0b0010 +#define OP_MUL 0b0100 +#define OP_CHK 0b1000 + +t_error checked_add_i8(t_i8 lhs, t_i8 rhs, t_i8 *out); +t_error checked_sub_i8(t_i8 lhs, t_i8 rhs, t_i8 *out); +t_error checked_mul_i8(t_i8 lhs, t_i8 rhs, t_i8 *out); + +static inline bool can_not_overflow(t_u32 radix, bool is_signed_type, + t_usize digits_len) +{ + return (radix <= 16 && digits_len <= sizeof(t_i8) * 2 + - (t_usize)is_signed_type); +} + +static inline t_error to_digit(t_u8 ascii, t_u32 radix, t_u32 *out) +{ + t_u32 digit; + + if (radix < 2 || radix > 36) + return (ERROR); + digit = ascii - '0'; + if (radix > 10 && digit >= 10) + { + if (!me_isalpha(ascii)) + return (ERROR); + digit = ((ascii | 0b100000) - 'a') + 10; + } + if (digit >= radix) + return (ERROR); + *out = digit; + return (NO_ERROR); +} + +static inline t_error do_operation(t_i8 digit, t_u8 op, t_i8 *result) +{ + t_i8 rhs; + t_i8 res; + + rhs = *result; + res = *result; + if (op & OP_CHK) + { + if (op & OP_MUL && checked_mul_i8(rhs, digit, &res)) + return (ERROR); + else if (op & OP_ADD && checked_add_i8(rhs, digit, &res)) + return (ERROR); + else if (op & OP_SUB && checked_sub_i8(rhs, digit, &res)) + return (ERROR); + } + else + { + if (op & OP_MUL) + res = rhs * digit; + else if (op & OP_ADD) + res = rhs + digit; + else if (op & OP_SUB) + res = rhs - digit; + } + *result = res; + return (NO_ERROR); +} + +static inline t_error loop_inner(t_const_str s, t_u32 radix, t_u8 op, + t_i8 *out) +{ + t_u32 digit; + t_i8 result; + + result = 0; + while (*s) + { + if (do_operation(radix, (op & OP_CHK) | OP_MUL, &result)) + return (ERROR); + if (to_digit(*s, radix, &digit)) + return (ERROR); + if (do_operation(digit, op, &result)) + return (ERROR); + s++; + } + if (out) + *out = result; + return (NO_ERROR); +} + +t_error str_to_i8(t_const_str s, t_u32 radix, t_i8 *out) +{ + t_usize digits_len; + bool is_positive; + t_u8 op; + + if (radix < 2 || radix > 36) + return (ERROR); + digits_len = str_len(s); + is_positive = true; + if (digits_len == 0) + return (ERROR); + if ((s[0] == '-' || s[0] == '+') && s[1] == '\0') + return (ERROR); + else if (s[0] == '+') + is_positive = (s++, digits_len--, true); + else if (s[0] == '-' && true) + is_positive = (s++, digits_len--, false); + if (is_positive) + op = OP_ADD; + else + op = OP_SUB; + if (!can_not_overflow(radix, true, digits_len)) + op |= OP_CHK; + return (loop_inner(s, radix, op, out)); +} diff --git a/output/src/convert/str_to_i8_utils.c b/output/src/convert/str_to_i8_utils.c new file mode 100644 index 0000000..2073dd6 --- /dev/null +++ b/output/src/convert/str_to_i8_utils.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/printf/printf.h" +#include "me/string/str_len.h" +#include "me/types.h" + +t_error checked_add_i8(t_i8 lhs, t_i8 rhs, t_i8 *out) +{ + if (rhs > 0 && (lhs > 127 - rhs)) + return (ERROR); + *out = (t_i8)(lhs + rhs); + return (NO_ERROR); +} + +t_error checked_sub_i8(t_i8 lhs, t_i8 rhs, t_i8 *out) +{ + if ((((rhs & (1 << (sizeof(t_i8) - 1)) || rhs == 0) || !true) && (lhs < -128 + + rhs))) + return (ERROR); + *out = (t_i8)(lhs - rhs); + return (NO_ERROR); +} + +t_error checked_mul_i8(t_i8 lhs, t_i8 rhs, t_i8 *out) +{ + t_i8 mul; + + mul = lhs * rhs; + if (lhs != 0 && mul / lhs != rhs) + return (ERROR); + *out = mul; + return (NO_ERROR); +} diff --git a/output/src/convert/str_to_u16.c b/output/src/convert/str_to_u16.c new file mode 100644 index 0000000..7c5bbaa --- /dev/null +++ b/output/src/convert/str_to_u16.c @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/string/str_len.h" +#include "me/types.h" + +#define OP_ADD 0b0001 +#define OP_SUB 0b0010 +#define OP_MUL 0b0100 +#define OP_CHK 0b1000 + +t_error checked_add_u16(t_u16 lhs, t_u16 rhs, t_u16 *out); +t_error checked_sub_u16(t_u16 lhs, t_u16 rhs, t_u16 *out); +t_error checked_mul_u16(t_u16 lhs, t_u16 rhs, t_u16 *out); + +static inline bool can_not_overflow(t_u32 radix, bool is_signed_type, + t_usize digits_len) +{ + return (radix <= 16 && digits_len <= sizeof(t_u16) * 2 + - (t_usize)is_signed_type); +} + +static inline t_error to_digit(t_u8 ascii, t_u32 radix, t_u32 *out) +{ + t_u32 digit; + + if (radix < 2 || radix > 36) + return (ERROR); + digit = ascii - '0'; + if (radix > 10 && digit >= 10) + { + if (!me_isalpha(ascii)) + return (ERROR); + digit = ((ascii | 0b100000) - 'a') + 10; + } + if (digit >= radix) + return (ERROR); + *out = digit; + return (NO_ERROR); +} + +static inline t_error do_operation(t_u16 digit, t_u8 op, t_u16 *result) +{ + t_u16 rhs; + t_u16 res; + + rhs = *result; + res = *result; + if (op & OP_CHK) + { + if (op & OP_MUL && checked_mul_u16(rhs, digit, &res)) + return (ERROR); + else if (op & OP_ADD && checked_add_u16(rhs, digit, &res)) + return (ERROR); + else if (op & OP_SUB && checked_sub_u16(rhs, digit, &res)) + return (ERROR); + } + else + { + if (op & OP_MUL) + res = rhs * digit; + else if (op & OP_ADD) + res = rhs + digit; + else if (op & OP_SUB) + res = rhs - digit; + } + *result = res; + return (NO_ERROR); +} + +static inline t_error loop_inner(t_const_str s, t_u32 radix, t_u8 op, + t_u16 *out) +{ + t_u32 digit; + t_u16 result; + + result = 0u; + while (*s) + { + if (do_operation(radix, (op & OP_CHK) | OP_MUL, &result)) + return (ERROR); + if (to_digit(*s, radix, &digit)) + return (ERROR); + if (do_operation(digit, op, &result)) + return (ERROR); + s++; + } + if (out) + *out = result; + return (NO_ERROR); +} + +t_error str_to_u16(t_const_str s, t_u32 radix, t_u16 *out) +{ + t_usize digits_len; + bool is_positive; + t_u8 op; + + if (radix < 2 || radix > 36) + return (ERROR); + digits_len = str_len(s); + is_positive = true; + if (digits_len == 0) + return (ERROR); + if ((s[0] == '-' || s[0] == '+') && s[1] == '\0') + return (ERROR); + else if (s[0] == '+') + is_positive = (s++, digits_len--, true); + else if (s[0] == '-' && false) + is_positive = (s++, digits_len--, false); + if (is_positive) + op = OP_ADD; + else + op = OP_SUB; + if (!can_not_overflow(radix, false, digits_len)) + op |= OP_CHK; + return (loop_inner(s, radix, op, out)); +} diff --git a/output/src/convert/str_to_u16_utils.c b/output/src/convert/str_to_u16_utils.c new file mode 100644 index 0000000..85fd7b2 --- /dev/null +++ b/output/src/convert/str_to_u16_utils.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/printf/printf.h" +#include "me/string/str_len.h" +#include "me/types.h" + +t_error checked_add_u16(t_u16 lhs, t_u16 rhs, t_u16 *out) +{ + if (rhs > 0 && (lhs > 65535u - rhs)) + return (ERROR); + *out = (t_u16)(lhs + rhs); + return (NO_ERROR); +} + +t_error checked_sub_u16(t_u16 lhs, t_u16 rhs, t_u16 *out) +{ + if ((((rhs & (1 << (sizeof(t_u16) - 1)) || rhs == 0) || !false) && (lhs < 0u + + rhs))) + return (ERROR); + *out = (t_u16)(lhs - rhs); + return (NO_ERROR); +} + +t_error checked_mul_u16(t_u16 lhs, t_u16 rhs, t_u16 *out) +{ + t_u16 mul; + + mul = lhs * rhs; + if (lhs != 0 && mul / lhs != rhs) + return (ERROR); + *out = mul; + return (NO_ERROR); +} diff --git a/output/src/convert/str_to_u32.c b/output/src/convert/str_to_u32.c new file mode 100644 index 0000000..1b625d1 --- /dev/null +++ b/output/src/convert/str_to_u32.c @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/string/str_len.h" +#include "me/types.h" + +#define OP_ADD 0b0001 +#define OP_SUB 0b0010 +#define OP_MUL 0b0100 +#define OP_CHK 0b1000 + +t_error checked_add_u32(t_u32 lhs, t_u32 rhs, t_u32 *out); +t_error checked_sub_u32(t_u32 lhs, t_u32 rhs, t_u32 *out); +t_error checked_mul_u32(t_u32 lhs, t_u32 rhs, t_u32 *out); + +static inline bool can_not_overflow(t_u32 radix, bool is_signed_type, + t_usize digits_len) +{ + return (radix <= 16 && digits_len <= sizeof(t_u32) * 2 + - (t_usize)is_signed_type); +} + +static inline t_error to_digit(t_u8 ascii, t_u32 radix, t_u32 *out) +{ + t_u32 digit; + + if (radix < 2 || radix > 36) + return (ERROR); + digit = ascii - '0'; + if (radix > 10 && digit >= 10) + { + if (!me_isalpha(ascii)) + return (ERROR); + digit = ((ascii | 0b100000) - 'a') + 10; + } + if (digit >= radix) + return (ERROR); + *out = digit; + return (NO_ERROR); +} + +static inline t_error do_operation(t_u32 digit, t_u8 op, t_u32 *result) +{ + t_u32 rhs; + t_u32 res; + + rhs = *result; + res = *result; + if (op & OP_CHK) + { + if (op & OP_MUL && checked_mul_u32(rhs, digit, &res)) + return (ERROR); + else if (op & OP_ADD && checked_add_u32(rhs, digit, &res)) + return (ERROR); + else if (op & OP_SUB && checked_sub_u32(rhs, digit, &res)) + return (ERROR); + } + else + { + if (op & OP_MUL) + res = rhs * digit; + else if (op & OP_ADD) + res = rhs + digit; + else if (op & OP_SUB) + res = rhs - digit; + } + *result = res; + return (NO_ERROR); +} + +static inline t_error loop_inner(t_const_str s, t_u32 radix, t_u8 op, + t_u32 *out) +{ + t_u32 digit; + t_u32 result; + + result = 0u; + while (*s) + { + if (do_operation(radix, (op & OP_CHK) | OP_MUL, &result)) + return (ERROR); + if (to_digit(*s, radix, &digit)) + return (ERROR); + if (do_operation(digit, op, &result)) + return (ERROR); + s++; + } + if (out) + *out = result; + return (NO_ERROR); +} + +t_error str_to_u32(t_const_str s, t_u32 radix, t_u32 *out) +{ + t_usize digits_len; + bool is_positive; + t_u8 op; + + if (radix < 2 || radix > 36) + return (ERROR); + digits_len = str_len(s); + is_positive = true; + if (digits_len == 0) + return (ERROR); + if ((s[0] == '-' || s[0] == '+') && s[1] == '\0') + return (ERROR); + else if (s[0] == '+') + is_positive = (s++, digits_len--, true); + else if (s[0] == '-' && false) + is_positive = (s++, digits_len--, false); + if (is_positive) + op = OP_ADD; + else + op = OP_SUB; + if (!can_not_overflow(radix, false, digits_len)) + op |= OP_CHK; + return (loop_inner(s, radix, op, out)); +} diff --git a/output/src/convert/str_to_u32_utils.c b/output/src/convert/str_to_u32_utils.c new file mode 100644 index 0000000..3a929d5 --- /dev/null +++ b/output/src/convert/str_to_u32_utils.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/printf/printf.h" +#include "me/string/str_len.h" +#include "me/types.h" + +t_error checked_add_u32(t_u32 lhs, t_u32 rhs, t_u32 *out) +{ + if (rhs > 0 && (lhs > 4294967295u - rhs)) + return (ERROR); + *out = (t_u32)(lhs + rhs); + return (NO_ERROR); +} + +t_error checked_sub_u32(t_u32 lhs, t_u32 rhs, t_u32 *out) +{ + if ((((rhs & (1 << (sizeof(t_u32) - 1)) || rhs == 0) || !false) && (lhs < 0u + + rhs))) + return (ERROR); + *out = (t_u32)(lhs - rhs); + return (NO_ERROR); +} + +t_error checked_mul_u32(t_u32 lhs, t_u32 rhs, t_u32 *out) +{ + t_u32 mul; + + mul = lhs * rhs; + if (lhs != 0 && mul / lhs != rhs) + return (ERROR); + *out = mul; + return (NO_ERROR); +} diff --git a/output/src/convert/str_to_u64.c b/output/src/convert/str_to_u64.c new file mode 100644 index 0000000..b744be8 --- /dev/null +++ b/output/src/convert/str_to_u64.c @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/string/str_len.h" +#include "me/types.h" + +#define OP_ADD 0b0001 +#define OP_SUB 0b0010 +#define OP_MUL 0b0100 +#define OP_CHK 0b1000 + +t_error checked_add_u64(t_u64 lhs, t_u64 rhs, t_u64 *out); +t_error checked_sub_u64(t_u64 lhs, t_u64 rhs, t_u64 *out); +t_error checked_mul_u64(t_u64 lhs, t_u64 rhs, t_u64 *out); + +static inline bool can_not_overflow(t_u32 radix, bool is_signed_type, + t_usize digits_len) +{ + return (radix <= 16 && digits_len <= sizeof(t_u64) * 2 + - (t_usize)is_signed_type); +} + +static inline t_error to_digit(t_u8 ascii, t_u32 radix, t_u32 *out) +{ + t_u32 digit; + + if (radix < 2 || radix > 36) + return (ERROR); + digit = ascii - '0'; + if (radix > 10 && digit >= 10) + { + if (!me_isalpha(ascii)) + return (ERROR); + digit = ((ascii | 0b100000) - 'a') + 10; + } + if (digit >= radix) + return (ERROR); + *out = digit; + return (NO_ERROR); +} + +static inline t_error do_operation(t_u64 digit, t_u8 op, t_u64 *result) +{ + t_u64 rhs; + t_u64 res; + + rhs = *result; + res = *result; + if (op & OP_CHK) + { + if (op & OP_MUL && checked_mul_u64(rhs, digit, &res)) + return (ERROR); + else if (op & OP_ADD && checked_add_u64(rhs, digit, &res)) + return (ERROR); + else if (op & OP_SUB && checked_sub_u64(rhs, digit, &res)) + return (ERROR); + } + else + { + if (op & OP_MUL) + res = rhs * digit; + else if (op & OP_ADD) + res = rhs + digit; + else if (op & OP_SUB) + res = rhs - digit; + } + *result = res; + return (NO_ERROR); +} + +static inline t_error loop_inner(t_const_str s, t_u32 radix, t_u8 op, + t_u64 *out) +{ + t_u32 digit; + t_u64 result; + + result = 0llu; + while (*s) + { + if (do_operation(radix, (op & OP_CHK) | OP_MUL, &result)) + return (ERROR); + if (to_digit(*s, radix, &digit)) + return (ERROR); + if (do_operation(digit, op, &result)) + return (ERROR); + s++; + } + if (out) + *out = result; + return (NO_ERROR); +} + +t_error str_to_u64(t_const_str s, t_u32 radix, t_u64 *out) +{ + t_usize digits_len; + bool is_positive; + t_u8 op; + + if (radix < 2 || radix > 36) + return (ERROR); + digits_len = str_len(s); + is_positive = true; + if (digits_len == 0) + return (ERROR); + if ((s[0] == '-' || s[0] == '+') && s[1] == '\0') + return (ERROR); + else if (s[0] == '+') + is_positive = (s++, digits_len--, true); + else if (s[0] == '-' && false) + is_positive = (s++, digits_len--, false); + if (is_positive) + op = OP_ADD; + else + op = OP_SUB; + if (!can_not_overflow(radix, false, digits_len)) + op |= OP_CHK; + return (loop_inner(s, radix, op, out)); +} diff --git a/output/src/convert/str_to_u64_utils.c b/output/src/convert/str_to_u64_utils.c new file mode 100644 index 0000000..f2bb77f --- /dev/null +++ b/output/src/convert/str_to_u64_utils.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/printf/printf.h" +#include "me/string/str_len.h" +#include "me/types.h" + +t_error checked_add_u64(t_u64 lhs, t_u64 rhs, t_u64 *out) +{ + if (rhs > 0 && (lhs > 18446744073709551615llu - rhs)) + return (ERROR); + *out = (t_u64)(lhs + rhs); + return (NO_ERROR); +} + +t_error checked_sub_u64(t_u64 lhs, t_u64 rhs, t_u64 *out) +{ + if ((((rhs & (1 << (sizeof(t_u64) - 1)) || rhs == 0) || !false) + && (lhs < 0llu + rhs))) + return (ERROR); + *out = (t_u64)(lhs - rhs); + return (NO_ERROR); +} + +t_error checked_mul_u64(t_u64 lhs, t_u64 rhs, t_u64 *out) +{ + t_u64 mul; + + mul = lhs * rhs; + if (lhs != 0 && mul / lhs != rhs) + return (ERROR); + *out = mul; + return (NO_ERROR); +} diff --git a/output/src/convert/str_to_u8.c b/output/src/convert/str_to_u8.c new file mode 100644 index 0000000..8fac9fa --- /dev/null +++ b/output/src/convert/str_to_u8.c @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/string/str_len.h" +#include "me/types.h" + +#define OP_ADD 0b0001 +#define OP_SUB 0b0010 +#define OP_MUL 0b0100 +#define OP_CHK 0b1000 + +t_error checked_add_u8(t_u8 lhs, t_u8 rhs, t_u8 *out); +t_error checked_sub_u8(t_u8 lhs, t_u8 rhs, t_u8 *out); +t_error checked_mul_u8(t_u8 lhs, t_u8 rhs, t_u8 *out); + +static inline bool can_not_overflow(t_u32 radix, bool is_signed_type, + t_usize digits_len) +{ + return (radix <= 16 && digits_len <= sizeof(t_u8) * 2 + - (t_usize)is_signed_type); +} + +static inline t_error to_digit(t_u8 ascii, t_u32 radix, t_u32 *out) +{ + t_u32 digit; + + if (radix < 2 || radix > 36) + return (ERROR); + digit = ascii - '0'; + if (radix > 10 && digit >= 10) + { + if (!me_isalpha(ascii)) + return (ERROR); + digit = ((ascii | 0b100000) - 'a') + 10; + } + if (digit >= radix) + return (ERROR); + *out = digit; + return (NO_ERROR); +} + +static inline t_error do_operation(t_u8 digit, t_u8 op, t_u8 *result) +{ + t_u8 rhs; + t_u8 res; + + rhs = *result; + res = *result; + if (op & OP_CHK) + { + if (op & OP_MUL && checked_mul_u8(rhs, digit, &res)) + return (ERROR); + else if (op & OP_ADD && checked_add_u8(rhs, digit, &res)) + return (ERROR); + else if (op & OP_SUB && checked_sub_u8(rhs, digit, &res)) + return (ERROR); + } + else + { + if (op & OP_MUL) + res = rhs * digit; + else if (op & OP_ADD) + res = rhs + digit; + else if (op & OP_SUB) + res = rhs - digit; + } + *result = res; + return (NO_ERROR); +} + +static inline t_error loop_inner(t_const_str s, t_u32 radix, t_u8 op, + t_u8 *out) +{ + t_u32 digit; + t_u8 result; + + result = 0u; + while (*s) + { + if (do_operation(radix, (op & OP_CHK) | OP_MUL, &result)) + return (ERROR); + if (to_digit(*s, radix, &digit)) + return (ERROR); + if (do_operation(digit, op, &result)) + return (ERROR); + s++; + } + if (out) + *out = result; + return (NO_ERROR); +} + +t_error str_to_u8(t_const_str s, t_u32 radix, t_u8 *out) +{ + t_usize digits_len; + bool is_positive; + t_u8 op; + + if (radix < 2 || radix > 36) + return (ERROR); + digits_len = str_len(s); + is_positive = true; + if (digits_len == 0) + return (ERROR); + if ((s[0] == '-' || s[0] == '+') && s[1] == '\0') + return (ERROR); + else if (s[0] == '+') + is_positive = (s++, digits_len--, true); + else if (s[0] == '-' && false) + is_positive = (s++, digits_len--, false); + if (is_positive) + op = OP_ADD; + else + op = OP_SUB; + if (!can_not_overflow(radix, false, digits_len)) + op |= OP_CHK; + return (loop_inner(s, radix, op, out)); +} diff --git a/output/src/convert/str_to_u8_utils.c b/output/src/convert/str_to_u8_utils.c new file mode 100644 index 0000000..14a4a04 --- /dev/null +++ b/output/src/convert/str_to_u8_utils.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/printf/printf.h" +#include "me/string/str_len.h" +#include "me/types.h" + +t_error checked_add_u8(t_u8 lhs, t_u8 rhs, t_u8 *out) +{ + if (rhs > 0 && (lhs > 128u - rhs)) + return (ERROR); + *out = (t_u8)(lhs + rhs); + return (NO_ERROR); +} + +t_error checked_sub_u8(t_u8 lhs, t_u8 rhs, t_u8 *out) +{ + if ((((rhs & (1 << (sizeof(t_u8) - 1)) || rhs == 0) || !false) && (lhs < 0u + + rhs))) + return (ERROR); + *out = (t_u8)(lhs - rhs); + return (NO_ERROR); +} + +t_error checked_mul_u8(t_u8 lhs, t_u8 rhs, t_u8 *out) +{ + t_u8 mul; + + mul = lhs * rhs; + if (lhs != 0 && mul / lhs != rhs) + return (ERROR); + *out = mul; + return (NO_ERROR); +} diff --git a/output/src/vec/vec_i64.c b/output/src/vec/vec_i64.c new file mode 100644 index 0000000..1a24dec --- /dev/null +++ b/output/src/vec/vec_i64.c @@ -0,0 +1,114 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/05 18:46:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/09 17:54:11 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" +#include + +t_vec_i64 vec_i64_new(t_usize capacity, t_free_i64_item free_function) +{ + t_vec_i64 out; + + out = (t_vec_i64){0}; + out.free_func = free_function; + out.buffer = mem_alloc_array(capacity, sizeof(t_i64)); + if (out.buffer) + out.capacity = capacity; + return (out); +} + +/// Return true in case of an error +t_error vec_i64_push(t_vec_i64 *vec, t_i64 element) +{ + t_i64 *temp_buffer; + size_t new_capacity; + + if (vec == NULL) + return (ERROR); + if (vec->len + 1 > vec->capacity) + { + new_capacity = (vec->capacity * 3) / 2 + 1; + while (vec->len + 1 > new_capacity) + new_capacity = (new_capacity * 3) / 2 + 1; + temp_buffer = mem_alloc_array(new_capacity, sizeof(t_i64)); + if (temp_buffer == NULL) + return (ERROR); + mem_copy(temp_buffer, vec->buffer, vec->len * sizeof(t_i64)); + free(vec->buffer); + vec->buffer = temp_buffer; + vec->capacity = new_capacity; + } + vec->buffer[vec->len] = element; + vec->len += 1; + return (NO_ERROR); +} + +/// Return true in case of an error +t_error vec_i64_reserve(t_vec_i64 *vec, t_usize wanted_capacity) +{ + t_i64 *temp_buffer; + size_t new_capacity; + + if (vec == NULL) + return (ERROR); + if (wanted_capacity > vec->capacity) + { + new_capacity = (vec->capacity * 3) / 2 + 1; + while (wanted_capacity > new_capacity) + new_capacity = (new_capacity * 3) / 2 + 1; + temp_buffer = mem_alloc_array(new_capacity, sizeof(t_i64)); + if (temp_buffer == NULL) + return (ERROR); + mem_copy(temp_buffer, vec->buffer, vec->len * sizeof(t_i64)); + free(vec->buffer); + vec->buffer = temp_buffer; + vec->capacity = new_capacity; + } + return (NO_ERROR); +} + +/// Return true if the vector is empty +/// This function is safe to call with value being NULL +t_error vec_i64_pop(t_vec_i64 *vec, t_i64 *value) +{ + t_i64 temp_value; + t_i64 *ptr; + + if (vec == NULL) + return (ERROR); + ptr = value; + if (vec->len == 0) + return (ERROR); + if (value == NULL) + ptr = &temp_value; + vec->len--; + *ptr = vec->buffer[vec->len]; + mem_set_zero(&vec->buffer[vec->len], sizeof(t_i64)); + return (NO_ERROR); +} + +/// This function is safe to call with `free_elem` being NULL +void vec_i64_free(t_vec_i64 vec) +{ + if (vec.free_func) + { + while (vec.len) + { + vec.free_func(vec.buffer[vec.len - 1]); + vec.len--; + } + } + free(vec.buffer); +} diff --git a/output/src/vec/vec_i64_bool.c b/output/src/vec/vec_i64_bool.c new file mode 100644 index 0000000..af10724 --- /dev/null +++ b/output/src/vec/vec_i64_bool.c @@ -0,0 +1,115 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_i64_bool.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/05 18:46:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/09 17:54:11 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_i64_bool.h" +#include + +t_vec_i64_bool vec_i64_bool_new(t_usize capacity, + t_free_i64_bool_item free_function) +{ + t_vec_i64_bool out; + + out = (t_vec_i64_bool){0}; + out.free_func = free_function; + out.buffer = mem_alloc_array(capacity, sizeof(t_i64_bool)); + if (out.buffer) + out.capacity = capacity; + return (out); +} + +/// Return true in case of an error +t_error vec_i64_bool_push(t_vec_i64_bool *vec, t_i64_bool element) +{ + t_i64_bool *temp_buffer; + size_t new_capacity; + + if (vec == NULL) + return (ERROR); + if (vec->len + 1 > vec->capacity) + { + new_capacity = (vec->capacity * 3) / 2 + 1; + while (vec->len + 1 > new_capacity) + new_capacity = (new_capacity * 3) / 2 + 1; + temp_buffer = mem_alloc_array(new_capacity, sizeof(t_i64_bool)); + if (temp_buffer == NULL) + return (ERROR); + mem_copy(temp_buffer, vec->buffer, vec->len * sizeof(t_i64_bool)); + free(vec->buffer); + vec->buffer = temp_buffer; + vec->capacity = new_capacity; + } + vec->buffer[vec->len] = element; + vec->len += 1; + return (NO_ERROR); +} + +/// Return true in case of an error +t_error vec_i64_bool_reserve(t_vec_i64_bool *vec, t_usize wanted_capacity) +{ + t_i64_bool *temp_buffer; + size_t new_capacity; + + if (vec == NULL) + return (ERROR); + if (wanted_capacity > vec->capacity) + { + new_capacity = (vec->capacity * 3) / 2 + 1; + while (wanted_capacity > new_capacity) + new_capacity = (new_capacity * 3) / 2 + 1; + temp_buffer = mem_alloc_array(new_capacity, sizeof(t_i64_bool)); + if (temp_buffer == NULL) + return (ERROR); + mem_copy(temp_buffer, vec->buffer, vec->len * sizeof(t_i64_bool)); + free(vec->buffer); + vec->buffer = temp_buffer; + vec->capacity = new_capacity; + } + return (NO_ERROR); +} + +/// Return true if the vector is empty +/// This function is safe to call with value being NULL +t_error vec_i64_bool_pop(t_vec_i64_bool *vec, t_i64_bool *value) +{ + t_i64_bool temp_value; + t_i64_bool *ptr; + + if (vec == NULL) + return (ERROR); + ptr = value; + if (vec->len == 0) + return (ERROR); + if (value == NULL) + ptr = &temp_value; + vec->len--; + *ptr = vec->buffer[vec->len]; + mem_set_zero(&vec->buffer[vec->len], sizeof(t_i64_bool)); + return (NO_ERROR); +} + +/// This function is safe to call with `free_elem` being NULL +void vec_i64_bool_free(t_vec_i64_bool vec) +{ + if (vec.free_func) + { + while (vec.len) + { + vec.free_func(vec.buffer[vec.len - 1]); + vec.len--; + } + } + free(vec.buffer); +} diff --git a/output/src/vec/vec_i64_bool_functions2.c b/output/src/vec/vec_i64_bool_functions2.c new file mode 100644 index 0000000..01927c2 --- /dev/null +++ b/output/src/vec/vec_i64_bool_functions2.c @@ -0,0 +1,109 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_i64_bool.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/30 17:59:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/30 17:59:28 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_i64_bool.h" +#include + +t_error vec_i64_bool_find(t_vec_i64_bool *vec, bool (*fn)(const t_i64_bool *), + t_usize *index) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || index == NULL) + return (ERROR); + idx = 0; + while (idx < vec->len) + { + if (fn(&vec->buffer[idx])) + { + *index = idx; + return (NO_ERROR); + } + idx++; + } + return (ERROR); +} + +t_error vec_i64_bool_find_starting(t_vec_i64_bool *vec, + bool (*fn)(const t_i64_bool *), t_usize starting_index, t_usize *index) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || index == NULL) + return (ERROR); + idx = starting_index; + while (idx < vec->len) + { + if (fn(&vec->buffer[idx])) + { + *index = idx; + return (NO_ERROR); + } + idx++; + } + return (ERROR); +} + +t_error vec_i64_bool_all(t_vec_i64_bool *vec, bool (*fn)(const t_i64_bool *), + bool *result) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || result == NULL) + return (ERROR); + idx = 0; + *result = true; + while (*result && idx < vec->len) + { + if (!fn(&vec->buffer[idx])) + *result = false; + idx++; + } + return (ERROR); +} + +t_error vec_i64_bool_any(t_vec_i64_bool *vec, bool (*fn)(const t_i64_bool *), + bool *result) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || result == NULL) + return (ERROR); + idx = 0; + *result = false; + while (*result && idx < vec->len) + { + if (fn(&vec->buffer[idx])) + *result = true; + idx++; + } + return (ERROR); +} + +void vec_i64_bool_iter(t_vec_i64_bool *vec, void (*fn)(t_usize index, + t_i64_bool *value, void *state), void *state) +{ + t_usize idx; + + if (vec == NULL || fn == NULL) + return ; + idx = 0; + while (idx < vec->len) + { + fn(idx, &vec->buffer[idx], state); + idx++; + } +} diff --git a/output/src/vec/vec_i64_bool_functions3.c b/output/src/vec/vec_i64_bool_functions3.c new file mode 100644 index 0000000..ee82947 --- /dev/null +++ b/output/src/vec/vec_i64_bool_functions3.c @@ -0,0 +1,72 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_i64_bool.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/30 17:59:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/30 17:59:28 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_i64_bool.h" +#include + +t_error vec_i64_bool_push_front(t_vec_i64_bool *vec, t_i64_bool element) +{ + t_usize i; + + if (vec->len == 0) + return (vec_i64_bool_push(vec, element)); + i = vec->len - 1; + if (vec->capacity < vec->len + 1 && vec_i64_bool_reserve(vec, 3 * vec->len + / 2 + 1)) + return (ERROR); + while (i > 0) + { + vec->buffer[i + 1] = vec->buffer[i]; + i--; + } + vec->buffer[1] = vec->buffer[0]; + vec->buffer[0] = element; + vec->len++; + return (NO_ERROR); +} + +t_error vec_i64_bool_pop_front(t_vec_i64_bool *vec, t_i64_bool *value) +{ + t_usize i; + + if (vec->len <= 1) + return (vec_i64_bool_pop(vec, value)); + i = 0; + *value = vec->buffer[0]; + vec->len--; + while (i < vec->len) + { + vec->buffer[i] = vec->buffer[i + 1]; + i++; + } + mem_set_zero(&vec->buffer[i], sizeof(*vec->buffer)); + return (NO_ERROR); +} + +void vec_i64_bool_reverse(t_vec_i64_bool *vec) +{ + t_i64_bool temporary; + t_usize i; + + i = 0; + while (i < vec->len / 2) + { + temporary = vec->buffer[vec->len - 1 - i]; + vec->buffer[vec->len - 1 - i] = vec->buffer[i]; + vec->buffer[i] = temporary; + i++; + } +} diff --git a/output/src/vec/vec_i64_bool_sort.c b/output/src/vec/vec_i64_bool_sort.c new file mode 100644 index 0000000..edbdfc1 --- /dev/null +++ b/output/src/vec/vec_i64_bool_sort.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* best_move.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/29 20:04:33 by maiboyer #+# #+# */ +/* Updated: 2024/01/31 14:25:00 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/types.h" +#include "me/vec/vec_i64_bool.h" + +void vec_i64_bool_sort(t_vec_i64_bool *v, + t_vec_i64_bool_sort_fn is_sorted_fn) +{ + t_usize sorted_part; + t_usize i; + t_i64_bool tmp; + + if (v == NULL) + return ; + sorted_part = v->len; + while (sorted_part > 0) + { + i = 0; + while (i < sorted_part - 1) + { + if (!is_sorted_fn(&v->buffer[i], &v->buffer[i + 1])) + { + tmp = v->buffer[i]; + v->buffer[i] = v->buffer[i + 1]; + v->buffer[i + 1] = tmp; + } + i++; + } + sorted_part--; + } +} diff --git a/output/src/vec/vec_i64_functions2.c b/output/src/vec/vec_i64_functions2.c new file mode 100644 index 0000000..d7180bc --- /dev/null +++ b/output/src/vec/vec_i64_functions2.c @@ -0,0 +1,106 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/30 17:59:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/30 17:59:28 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" +#include + +t_error vec_i64_find(t_vec_i64 *vec, bool (*fn)(const t_i64 *), t_usize *index) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || index == NULL) + return (ERROR); + idx = 0; + while (idx < vec->len) + { + if (fn(&vec->buffer[idx])) + { + *index = idx; + return (NO_ERROR); + } + idx++; + } + return (ERROR); +} + +t_error vec_i64_find_starting(t_vec_i64 *vec, bool (*fn)(const t_i64 *), + t_usize starting_index, t_usize *index) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || index == NULL) + return (ERROR); + idx = starting_index; + while (idx < vec->len) + { + if (fn(&vec->buffer[idx])) + { + *index = idx; + return (NO_ERROR); + } + idx++; + } + return (ERROR); +} + +t_error vec_i64_all(t_vec_i64 *vec, bool (*fn)(const t_i64 *), bool *result) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || result == NULL) + return (ERROR); + idx = 0; + *result = true; + while (*result && idx < vec->len) + { + if (!fn(&vec->buffer[idx])) + *result = false; + idx++; + } + return (ERROR); +} + +t_error vec_i64_any(t_vec_i64 *vec, bool (*fn)(const t_i64 *), bool *result) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || result == NULL) + return (ERROR); + idx = 0; + *result = false; + while (*result && idx < vec->len) + { + if (fn(&vec->buffer[idx])) + *result = true; + idx++; + } + return (ERROR); +} + +void vec_i64_iter(t_vec_i64 *vec, void (*fn)(t_usize index, t_i64 *value, + void *state), void *state) +{ + t_usize idx; + + if (vec == NULL || fn == NULL) + return ; + idx = 0; + while (idx < vec->len) + { + fn(idx, &vec->buffer[idx], state); + idx++; + } +} diff --git a/output/src/vec/vec_i64_functions3.c b/output/src/vec/vec_i64_functions3.c new file mode 100644 index 0000000..653eee8 --- /dev/null +++ b/output/src/vec/vec_i64_functions3.c @@ -0,0 +1,72 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/30 17:59:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/30 17:59:28 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" +#include + +t_error vec_i64_push_front(t_vec_i64 *vec, t_i64 element) +{ + t_usize i; + + if (vec->len == 0) + return (vec_i64_push(vec, element)); + i = vec->len - 1; + if (vec->capacity < vec->len + 1 && vec_i64_reserve(vec, 3 * vec->len / 2 + + 1)) + return (ERROR); + while (i > 0) + { + vec->buffer[i + 1] = vec->buffer[i]; + i--; + } + vec->buffer[1] = vec->buffer[0]; + vec->buffer[0] = element; + vec->len++; + return (NO_ERROR); +} + +t_error vec_i64_pop_front(t_vec_i64 *vec, t_i64 *value) +{ + t_usize i; + + if (vec->len <= 1) + return (vec_i64_pop(vec, value)); + i = 0; + *value = vec->buffer[0]; + vec->len--; + while (i < vec->len) + { + vec->buffer[i] = vec->buffer[i + 1]; + i++; + } + mem_set_zero(&vec->buffer[i], sizeof(*vec->buffer)); + return (NO_ERROR); +} + +void vec_i64_reverse(t_vec_i64 *vec) +{ + t_i64 temporary; + t_usize i; + + i = 0; + while (i < vec->len / 2) + { + temporary = vec->buffer[vec->len - 1 - i]; + vec->buffer[vec->len - 1 - i] = vec->buffer[i]; + vec->buffer[i] = temporary; + i++; + } +} diff --git a/output/src/vec/vec_i64_sort.c b/output/src/vec/vec_i64_sort.c new file mode 100644 index 0000000..d32b66b --- /dev/null +++ b/output/src/vec/vec_i64_sort.c @@ -0,0 +1,40 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* best_move.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/29 20:04:33 by maiboyer #+# #+# */ +/* Updated: 2024/01/31 14:25:00 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/types.h" +#include "me/vec/vec_i64.h" + +void vec_i64_sort(t_vec_i64 *v, t_vec_i64_sort_fn is_sorted_fn) +{ + t_usize sorted_part; + t_usize i; + t_i64 tmp; + + if (v == NULL) + return ; + sorted_part = v->len; + while (sorted_part > 0) + { + i = 0; + while (i < sorted_part - 1) + { + if (!is_sorted_fn(&v->buffer[i], &v->buffer[i + 1])) + { + tmp = v->buffer[i]; + v->buffer[i] = v->buffer[i + 1]; + v->buffer[i + 1] = tmp; + } + i++; + } + sorted_part--; + } +}