Added <num>_to_str functions

This commit is contained in:
Maieul BOYER 2024-07-16 19:38:27 +02:00
parent aafd056f49
commit 698d1088e2
No known key found for this signature in database
21 changed files with 963 additions and 60 deletions

View file

@ -6,7 +6,7 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */ /* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/11 17:22:29 by maiboyer #+# #+# */ /* Created: 2024/07/11 17:22:29 by maiboyer #+# #+# */
/* Updated: 2024/07/15 18:40:19 by maiboyer ### ########.fr */ /* Updated: 2024/07/16 13:27:18 by maiboyer ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -95,23 +95,49 @@ t_error _get_expansion_value(t_ast_expansion *self, t_state *state, t_expansion_
return (NO_ERROR); return (NO_ERROR);
} }
t_error _handle_no_operator(t_ast_expansion *self, t_state *state, t_expansion_result *out) NOT_DONE; #include "me/convert/itoa.h"
t_error _handle_len_operator(t_ast_expansion *self, t_state *state, t_expansion_result *out) NOT_DONE;
t_error _handle_assign_operator(t_ast_expansion *self, t_state *state, t_expansion_result *out) NOT_DONE;
t_error _handle_assign_colon_operator(t_ast_expansion *self, t_state *state, t_expansion_result *out) NOT_DONE;
t_error _handle_alternate_operator(t_ast_expansion *self, t_state *state, t_expansion_result *out) NOT_DONE;
t_error _handle_alternate_colon_operator(t_ast_expansion *self, t_state *state, t_expansion_result *out) NOT_DONE;
t_error _handle_default_operator(t_ast_expansion *self, t_state *state, t_expansion_result *out) NOT_DONE;
t_error _handle_default_colon_operator(t_ast_expansion *self, t_state *state, t_expansion_result *out) NOT_DONE;
t_error _handle_error_operator(t_ast_expansion *self, t_state *state, t_expansion_result *out) NOT_DONE;
t_error _handle_error_colon_operator(t_ast_expansion *self, t_state *state, t_expansion_result *out) NOT_DONE;
t_error _handle_suffix_pattern_smallest_operator(t_ast_expansion *self, t_state *state, t_expansion_result *out) NOT_DONE; t_error _handle_len_operator(t_ast_expansion *self, t_state *state, t_expansion_result *value)
t_error _handle_suffix_pattern_longest_operator(t_ast_expansion *self, t_state *state, t_expansion_result *out) NOT_DONE; {
t_error _handle_prefix_pattern_smallest_operator(t_ast_expansion *self, t_state *state, t_expansion_result *out) NOT_DONE; t_str len_str;
t_error _handle_prefix_pattern_longest_operator(t_ast_expansion *self, t_state *state, t_expansion_result *out) NOT_DONE; t_usize len;
t_error _get_op_func(t_ast_expansion *self, t_error (**op_func)()) if (value->exists && value->str != NULL)
len = str_len(value->str);
else
len = 0;
len_str = me_itoa(len);
mem_free(value->str);
value->exists = true;
value->str = len_str;
return (NO_ERROR);
};
t_error _handle_no_operator(t_ast_expansion *self, t_state *state, t_expansion_result *value)
{
(void)(self);
(void)(state);
(void)(value);
if (self == NULL || state == NULL || value == NULL)
return (ERROR);
return (NO_ERROR);
};
t_error _handle_assign_operator(t_ast_expansion *self, t_state *state, t_expansion_result *value) NOT_DONE;
t_error _handle_assign_colon_operator(t_ast_expansion *self, t_state *state, t_expansion_result *value) NOT_DONE;
t_error _handle_alternate_operator(t_ast_expansion *self, t_state *state, t_expansion_result *value) NOT_DONE;
t_error _handle_alternate_colon_operator(t_ast_expansion *self, t_state *state, t_expansion_result *value) NOT_DONE;
t_error _handle_default_operator(t_ast_expansion *self, t_state *state, t_expansion_result *value) NOT_DONE;
t_error _handle_default_colon_operator(t_ast_expansion *self, t_state *state, t_expansion_result *value) NOT_DONE;
t_error _handle_error_operator(t_ast_expansion *self, t_state *state, t_expansion_result *value) NOT_DONE;
t_error _handle_error_colon_operator(t_ast_expansion *self, t_state *state, t_expansion_result *value) NOT_DONE;
t_error _handle_suffix_pattern_smallest_operator(t_ast_expansion *self, t_state *state, t_expansion_result *value) NOT_DONE;
t_error _handle_suffix_pattern_longest_operator(t_ast_expansion *self, t_state *state, t_expansion_result *value) NOT_DONE;
t_error _handle_prefix_pattern_smallest_operator(t_ast_expansion *self, t_state *state, t_expansion_result *value) NOT_DONE;
t_error _handle_prefix_pattern_longest_operator(t_ast_expansion *self, t_state *state, t_expansion_result *value) NOT_DONE;
t_error _get_op_func(t_ast_expansion *self, t_error (**op_func)(t_ast_expansion *self, t_state *state, t_expansion_result *value))
{ {
if (self == NULL || op_func == NULL) if (self == NULL || op_func == NULL)
return (ERROR); return (ERROR);
@ -144,16 +170,17 @@ t_error _get_op_func(t_ast_expansion *self, t_error (**op_func)())
return (ERROR); return (ERROR);
} }
t_error _handle_expansion_operator(t_ast_expansion *self, t_state *state, t_expansion_result *out) t_error _handle_expansion_operator(t_ast_expansion *self, t_state *state, t_expansion_result *value)
{ {
t_str value; t_error (*op_func)(t_ast_expansion *self, t_state *state, t_expansion_result *value);
t_error (*op_func)();
if (self == NULL || state == NULL || out == NULL) if (self == NULL || state == NULL || value == NULL)
return (ERROR); return (ERROR);
if (_get_op_func(self, &op_func)) if (_get_op_func(self, &op_func))
return (ERROR); return (ERROR);
return (ERROR); if (op_func(self, state, value))
return (ERROR);
return (NO_ERROR);
} }
// End Internals funcs // End Internals funcs
@ -195,21 +222,18 @@ t_error run_word(t_ast_word *word, t_state *state, void *out) NOT_DONE;
t_error run_expansion(t_ast_expansion *self, t_state *state, t_expansion_result *out) t_error run_expansion(t_ast_expansion *self, t_state *state, t_expansion_result *out)
{ {
t_expansion_result ret; t_expansion_result ret;
bool is_special_var;
if (_is_special_var(self)) is_special_var = _is_special_var(self);
{ if (is_special_var && _run_expansion_special_var(self, state, &ret))
if (_run_expansion_special_var(self, state, &ret)) return (ERROR);
return (ERROR); if (!is_special_var && _get_expansion_value(self, state, &ret))
} return (ERROR);
else
{
if (_get_expansion_value(self, state, &ret))
return (ERROR);
}
if (_handle_expansion_operator(self, state, &ret)) if (_handle_expansion_operator(self, state, &ret))
return (ERROR); return (ERROR);
if (self->len_operator && _handle_len_operator(self, state, &ret))
return (ERROR); return (ERROR);
return (*out = ret, NO_ERROR);
} }
// FUNCTIONS // FUNCTIONS

View file

@ -1,3 +1,7 @@
convert/i16_to_str
convert/i32_to_str
convert/i64_to_str
convert/i8_to_str
convert/str_to_i16 convert/str_to_i16
convert/str_to_i16_utils convert/str_to_i16_utils
convert/str_to_i32 convert/str_to_i32
@ -14,6 +18,10 @@ convert/str_to_u64
convert/str_to_u64_utils convert/str_to_u64_utils
convert/str_to_u8 convert/str_to_u8
convert/str_to_u8_utils convert/str_to_u8_utils
convert/u16_to_str
convert/u32_to_str
convert/u64_to_str
convert/u8_to_str
vec/buf_str/buf_str vec/buf_str/buf_str
vec/buf_str/buf_str_functions2 vec/buf_str/buf_str_functions2
vec/buf_str/buf_str_functions3 vec/buf_str/buf_str_functions3

View file

@ -0,0 +1,51 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* str_to_i64.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */
/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "me/char/char.h"
#include "me/convert/numbers_to_str.h"
#include "me/str/str.h"
#include "me/types.h"
t_error _format_u64(t_num_str args, t_str *out);
t_error C__PREFIX___to_str_base_prefix(C__TYPE__ val, t_str base, t_str prefix,
t_str *out)
{
union u_nums value;
bool is_nonnegative;
if (out == NULL || base == NULL || prefix == NULL)
return (ERROR);
value.C__FIELD__ = val;
is_nonnegative = val < 0;
if (is_nonnegative)
value.C__UFIELD__ = ~value.C__UFIELD__ + 1;
return (_format_u64((t_num_str){.value = value.u64, \
.is_nonnegative = is_nonnegative, \
.base = base, \
.prefix = prefix}, \
out));
}
t_error C__PREFIX___to_str_base(C__TYPE__ val, t_str base, t_str *out)
{
if (out == NULL || base == NULL)
return (ERROR);
return (C__PREFIX___to_str_base_prefix(val, base, "", out));
}
t_error C__PREFIX___to_str(C__TYPE__ val, t_str *out)
{
if (out == NULL)
return (ERROR);
return (C__PREFIX___to_str_base_prefix(val, "0123456789", "", out));
}

View file

@ -0,0 +1,239 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* numbers_to_str.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/16 17:18:47 by maiboyer #+# #+# */
/* Updated: 2024/07/16 17:19:31 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef NUMBERS_TO_STR_H
#define NUMBERS_TO_STR_H
#include "me/types.h"
typedef struct s_num_str t_num_str;
typedef struct s_num_str_state t_num_str_state;
struct s_num_str
{
t_u64 value;
bool is_nonnegative;
t_str base;
t_str prefix;
};
struct s_num_str_state
{
bool print;
bool zero;
char buffer[40];
t_str base;
t_u64 base_len;
t_u64 modulus;
t_u64 value;
t_usize idx;
};
union u_nums {
t_u64 u64;
t_i64 i64;
t_u32 u32;
t_i32 i32;
t_u16 u16;
t_i16 i16;
t_u8 u8;
t_i8 i8;
};
/// @brief Convert a signed 8-bit integer to a string with a base and a prefix.
/// @param val The signed 8-bit integer to convert.
/// @param base The base to use for the conversion.
/// @param prefix The prefix to use for the conversion.
/// @param out The output string.
/// @return True in case of error, false otherwise.
/// @note The base must be a string of at least 2 characters and no duplicates.
t_error i8_to_str_base_prefix(t_i8 val, t_str base, t_str prefix, t_str *out);
/// @brief Convert a signed 8-bit integer to a string with a base
/// @param val The signed 8-bit integer to convert.
/// @param base The base to use for the conversion.
/// @param out The output string.
/// @return True in case of error, false otherwise.
/// @note The base must be a string of at least 2 characters and no duplicates.
t_error i8_to_str_base(t_i8 val, t_str base, t_str *out);
/// @brief Convert a signed 8-bit integer to a string.
/// @param val The signed 8-bit integer to convert.
/// @param out The output string.
/// @return True in case of error, false otherwise.
t_error i8_to_str(t_i8 val, t_str *out);
/// @brief Convert a unsigned 8-bit integer to a string with a base and a prefix.
/// @param val The unsigned 8-bit integer to convert.
/// @param base The base to use for the conversion.
/// @param prefix The prefix to use for the conversion.
/// @param out The output string.
/// @return True in case of error, false otherwise.
/// @note The base must be a string of at least 2 characters and no duplicates.
t_error u8_to_str_base_prefix(t_u8 val, t_str base, t_str prefix, t_str *out);
/// @brief Convert a unsigned 8-bit integer to a string with a base
/// @param val The unsigned 8-bit integer to convert.
/// @param base The base to use for the conversion.
/// @param out The output string.
/// @return True in case of error, false otherwise.
/// @note The base must be a string of at least 2 characters and no duplicates.
t_error u8_to_str_base(t_u8 val, t_str base, t_str *out);
/// @brief Convert a unsigned 8-bit integer to a string.
/// @param val The unsigned 8-bit integer to convert.
/// @param out The output string.
/// @return True in case of error, false otherwise.
t_error u8_to_str(t_u8 val, t_str *out);
/// @brief Convert a signed 16-bit integer to a string with a base and a prefix.
/// @param val The signed 16-bit integer to convert.
/// @param base The base to use for the conversion.
/// @param prefix The prefix to use for the conversion.
/// @param out The output string.
/// @return True in case of error, false otherwise.
/// @note The base must be a string of at least 2 characters and no duplicates.
t_error i16_to_str_base_prefix(t_i16 val, t_str base, t_str prefix, t_str *out);
/// @brief Convert a signed 16-bit integer to a string with a base
/// @param val The signed 16-bit integer to convert.
/// @param base The base to use for the conversion.
/// @param out The output string.
/// @return True in case of error, false otherwise.
/// @note The base must be a string of at least 2 characters and no duplicates.
t_error i16_to_str_base(t_i16 val, t_str base, t_str *out);
/// @brief Convert a signed 16-bit integer to a string.
/// @param val The signed 16-bit integer to convert.
/// @param out The output string.
/// @return True in case of error, false otherwise.
t_error i16_to_str(t_i16 val, t_str *out);
/// @brief Convert a unsigned 16-bit integer to a string with a base and a prefix.
/// @param val The unsigned 16-bit integer to convert.
/// @param base The base to use for the conversion.
/// @param prefix The prefix to use for the conversion.
/// @param out The output string.
/// @return True in case of error, false otherwise.
/// @note The base must be a string of at least 2 characters and no duplicates.
t_error u16_to_str_base_prefix(t_u16 val, t_str base, t_str prefix, t_str *out);
/// @brief Convert a unsigned 16-bit integer to a string with a base
/// @param val The unsigned 16-bit integer to convert.
/// @param base The base to use for the conversion.
/// @param out The output string.
/// @return True in case of error, false otherwise.
/// @note The base must be a string of at least 2 characters and no duplicates.
t_error u16_to_str_base(t_u16 val, t_str base, t_str *out);
/// @brief Convert a unsigned 16-bit integer to a string.
/// @param val The unsigned 16-bit integer to convert.
/// @param out The output string.
/// @return True in case of error, false otherwise.
t_error u16_to_str(t_u16 val, t_str *out);
/// @brief Convert a signed 32-bit integer to a string with a base and a prefix.
/// @param val The signed 32-bit integer to convert.
/// @param base The base to use for the conversion.
/// @param prefix The prefix to use for the conversion.
/// @param out The output string.
/// @return True in case of error, false otherwise.
/// @note The base must be a string of at least 2 characters and no duplicates.
t_error i32_to_str_base_prefix(t_i32 val, t_str base, t_str prefix, t_str *out);
/// @brief Convert a signed 32-bit integer to a string with a base
/// @param val The signed 32-bit integer to convert.
/// @param base The base to use for the conversion.
/// @param out The output string.
/// @return True in case of error, false otherwise.
/// @note The base must be a string of at least 2 characters and no duplicates.
t_error i32_to_str_base(t_i32 val, t_str base, t_str *out);
/// @brief Convert a signed 32-bit integer to a string.
/// @param val The signed 32-bit integer to convert.
/// @param out The output string.
/// @return True in case of error, false otherwise.
t_error i32_to_str(t_i32 val, t_str *out);
/// @brief Convert a unsigned 32-bit integer to a string with a base and a prefix.
/// @param val The unsigned 32-bit integer to convert.
/// @param base The base to use for the conversion.
/// @param prefix The prefix to use for the conversion.
/// @param out The output string.
/// @return True in case of error, false otherwise.
/// @note The base must be a string of at least 2 characters and no duplicates.
t_error u32_to_str_base_prefix(t_u32 val, t_str base, t_str prefix, t_str *out);
/// @brief Convert a unsigned 32-bit integer to a string with a base
/// @param val The unsigned 32-bit integer to convert.
/// @param base The base to use for the conversion.
/// @param out The output string.
/// @return True in case of error, false otherwise.
/// @note The base must be a string of at least 2 characters and no duplicates.
t_error u32_to_str_base(t_u32 val, t_str base, t_str *out);
/// @brief Convert a unsigned 32-bit integer to a string.
/// @param val The unsigned 32-bit integer to convert.
/// @param out The output string.
/// @return True in case of error, false otherwise.
t_error u32_to_str(t_u32 val, t_str *out);
/// @brief Convert a signed 64-bit integer to a string with a base and a prefix.
/// @param val The signed 64-bit integer to convert.
/// @param base The base to use for the conversion.
/// @param prefix The prefix to use for the conversion.
/// @param out The output string.
/// @return True in case of error, false otherwise.
/// @note The base must be a string of at least 2 characters and no duplicates.
t_error i64_to_str_base_prefix(t_i64 val, t_str base, t_str prefix, t_str *out);
/// @brief Convert a signed 64-bit integer to a string with a base
/// @param val The signed 64-bit integer to convert.
/// @param base The base to use for the conversion.
/// @param out The output string.
/// @return True in case of error, false otherwise.
/// @note The base must be a string of at least 2 characters and no duplicates.
t_error i64_to_str_base(t_i64 val, t_str base, t_str *out);
/// @brief Convert a signed 64-bit integer to a string.
/// @param val The signed 64-bit integer to convert.
/// @param out The output string.
/// @return True in case of error, false otherwise.
t_error i64_to_str(t_i64 val, t_str *out);
/// @brief Convert a unsigned 64-bit integer to a string with a base and a prefix.
/// @param val The unsigned 64-bit integer to convert.
/// @param base The base to use for the conversion.
/// @param prefix The prefix to use for the conversion.
/// @param out The output string.
/// @return True in case of error, false otherwise.
/// @note The base must be a string of at least 2 characters and no duplicates.
t_error u64_to_str_base_prefix(t_u64 val, t_str base, t_str prefix, t_str *out);
/// @brief Convert a unsigned 64-bit integer to a string with a base
/// @param val The unsigned 64-bit integer to convert.
/// @param base The base to use for the conversion.
/// @param out The output string.
/// @return True in case of error, false otherwise.
/// @note The base must be a string of at least 2 characters and no duplicates.
t_error u64_to_str_base(t_u64 val, t_str base, t_str *out);
/// @brief Convert a unsigned 64-bit integer to a string.
/// @param val The unsigned 64-bit integer to convert.
/// @param out The output string.
/// @return True in case of error, false otherwise.
t_error u64_to_str(t_u64 val, t_str *out);
#endif /* NUMBERS_TO_STR_H */

View file

@ -37,6 +37,79 @@ replace.C__MIN__ = "value"
replace.C__ZERO__ = "value" replace.C__ZERO__ = "value"
replace.C__SIGNED_TYPE__ = "bool" replace.C__SIGNED_TYPE__ = "bool"
[definition.num_to_str]
headers = []
sources = ["generic_sources/src/convert/C__PREFIX___to_str.c__TEMPLATE__"]
replace.C__TYPE__ = "type"
replace.C__PREFIX__ = "prefix"
replace.C__FIELD__ = "type"
replace.C__UFIELD__ = "type"
[[create.num_to_str]]
sources_output = "src/convert/"
headers_output = ""
replace.C__TYPE__ = "t_i64"
replace.C__UFIELD__ = "u64"
replace.C__FIELD__ = "i64"
replace.C__PREFIX__ = "i64"
[[create.num_to_str]]
sources_output = "src/convert/"
headers_output = ""
replace.C__TYPE__ = "t_u64"
replace.C__UFIELD__ = "u64"
replace.C__FIELD__ = "u64"
replace.C__PREFIX__ = "u64"
[[create.num_to_str]]
sources_output = "src/convert/"
headers_output = ""
replace.C__TYPE__ = "t_i32"
replace.C__UFIELD__ = "u32"
replace.C__FIELD__ = "i32"
replace.C__PREFIX__ = "i32"
[[create.num_to_str]]
sources_output = "src/convert/"
headers_output = ""
replace.C__TYPE__ = "t_u32"
replace.C__UFIELD__ = "u32"
replace.C__FIELD__ = "u32"
replace.C__PREFIX__ = "u32"
[[create.num_to_str]]
sources_output = "src/convert/"
headers_output = ""
replace.C__TYPE__ = "t_i16"
replace.C__UFIELD__ = "u16"
replace.C__FIELD__ = "i16"
replace.C__PREFIX__ = "i16"
[[create.num_to_str]]
sources_output = "src/convert/"
headers_output = ""
replace.C__TYPE__ = "t_u16"
replace.C__UFIELD__ = "u16"
replace.C__FIELD__ = "u16"
replace.C__PREFIX__ = "u16"
[[create.num_to_str]]
sources_output = "src/convert/"
headers_output = ""
replace.C__TYPE__ = "t_i8"
replace.C__UFIELD__ = "u8"
replace.C__FIELD__ = "i8"
replace.C__PREFIX__ = "i8"
[[create.num_to_str]]
sources_output = "src/convert/"
headers_output = ""
replace.C__TYPE__ = "t_u8"
replace.C__UFIELD__ = "u8"
replace.C__FIELD__ = "u8"
replace.C__PREFIX__ = "u8"
[[create.str_to_num]] [[create.str_to_num]]
sources_output = "src/convert/" sources_output = "src/convert/"
headers_output = "" headers_output = ""

View file

@ -0,0 +1,51 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* str_to_i64.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */
/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "me/char/char.h"
#include "me/convert/numbers_to_str.h"
#include "me/str/str.h"
#include "me/types.h"
t_error _format_u64(t_num_str args, t_str *out);
t_error i16_to_str_base_prefix(t_i16 val, t_str base, t_str prefix,
t_str *out)
{
union u_nums value;
bool is_nonnegative;
if (out == NULL || base == NULL || prefix == NULL)
return (ERROR);
value.i16 = val;
is_nonnegative = val < 0;
if (is_nonnegative)
value.u16 = ~value.u16 + 1;
return (_format_u64((t_num_str){.value = value.u64, \
.is_nonnegative = is_nonnegative, \
.base = base, \
.prefix = prefix}, \
out));
}
t_error i16_to_str_base(t_i16 val, t_str base, t_str *out)
{
if (out == NULL || base == NULL)
return (ERROR);
return (i16_to_str_base_prefix(val, base, "", out));
}
t_error i16_to_str(t_i16 val, t_str *out)
{
if (out == NULL)
return (ERROR);
return (i16_to_str_base_prefix(val, "0123456789", "", out));
}

View file

@ -0,0 +1,51 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* str_to_i64.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */
/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "me/char/char.h"
#include "me/convert/numbers_to_str.h"
#include "me/str/str.h"
#include "me/types.h"
t_error _format_u64(t_num_str args, t_str *out);
t_error i32_to_str_base_prefix(t_i32 val, t_str base, t_str prefix,
t_str *out)
{
union u_nums value;
bool is_nonnegative;
if (out == NULL || base == NULL || prefix == NULL)
return (ERROR);
value.i32 = val;
is_nonnegative = val < 0;
if (is_nonnegative)
value.u32 = ~value.u32 + 1;
return (_format_u64((t_num_str){.value = value.u64, \
.is_nonnegative = is_nonnegative, \
.base = base, \
.prefix = prefix}, \
out));
}
t_error i32_to_str_base(t_i32 val, t_str base, t_str *out)
{
if (out == NULL || base == NULL)
return (ERROR);
return (i32_to_str_base_prefix(val, base, "", out));
}
t_error i32_to_str(t_i32 val, t_str *out)
{
if (out == NULL)
return (ERROR);
return (i32_to_str_base_prefix(val, "0123456789", "", out));
}

View file

@ -0,0 +1,51 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* str_to_i64.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */
/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "me/char/char.h"
#include "me/convert/numbers_to_str.h"
#include "me/str/str.h"
#include "me/types.h"
t_error _format_u64(t_num_str args, t_str *out);
t_error i64_to_str_base_prefix(t_i64 val, t_str base, t_str prefix,
t_str *out)
{
union u_nums value;
bool is_nonnegative;
if (out == NULL || base == NULL || prefix == NULL)
return (ERROR);
value.i64 = val;
is_nonnegative = val < 0;
if (is_nonnegative)
value.u64 = ~value.u64 + 1;
return (_format_u64((t_num_str){.value = value.u64, \
.is_nonnegative = is_nonnegative, \
.base = base, \
.prefix = prefix}, \
out));
}
t_error i64_to_str_base(t_i64 val, t_str base, t_str *out)
{
if (out == NULL || base == NULL)
return (ERROR);
return (i64_to_str_base_prefix(val, base, "", out));
}
t_error i64_to_str(t_i64 val, t_str *out)
{
if (out == NULL)
return (ERROR);
return (i64_to_str_base_prefix(val, "0123456789", "", out));
}

View file

@ -0,0 +1,51 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* str_to_i64.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */
/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "me/char/char.h"
#include "me/convert/numbers_to_str.h"
#include "me/str/str.h"
#include "me/types.h"
t_error _format_u64(t_num_str args, t_str *out);
t_error i8_to_str_base_prefix(t_i8 val, t_str base, t_str prefix,
t_str *out)
{
union u_nums value;
bool is_nonnegative;
if (out == NULL || base == NULL || prefix == NULL)
return (ERROR);
value.i8 = val;
is_nonnegative = val < 0;
if (is_nonnegative)
value.u8 = ~value.u8 + 1;
return (_format_u64((t_num_str){.value = value.u64, \
.is_nonnegative = is_nonnegative, \
.base = base, \
.prefix = prefix}, \
out));
}
t_error i8_to_str_base(t_i8 val, t_str base, t_str *out)
{
if (out == NULL || base == NULL)
return (ERROR);
return (i8_to_str_base_prefix(val, base, "", out));
}
t_error i8_to_str(t_i8 val, t_str *out)
{
if (out == NULL)
return (ERROR);
return (i8_to_str_base_prefix(val, "0123456789", "", out));
}

View file

@ -0,0 +1,51 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* str_to_i64.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */
/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "me/char/char.h"
#include "me/convert/numbers_to_str.h"
#include "me/str/str.h"
#include "me/types.h"
t_error _format_u64(t_num_str args, t_str *out);
t_error u16_to_str_base_prefix(t_u16 val, t_str base, t_str prefix,
t_str *out)
{
union u_nums value;
bool is_nonnegative;
if (out == NULL || base == NULL || prefix == NULL)
return (ERROR);
value.u16 = val;
is_nonnegative = val < 0;
if (is_nonnegative)
value.u16 = ~value.u16 + 1;
return (_format_u64((t_num_str){.value = value.u64, \
.is_nonnegative = is_nonnegative, \
.base = base, \
.prefix = prefix}, \
out));
}
t_error u16_to_str_base(t_u16 val, t_str base, t_str *out)
{
if (out == NULL || base == NULL)
return (ERROR);
return (u16_to_str_base_prefix(val, base, "", out));
}
t_error u16_to_str(t_u16 val, t_str *out)
{
if (out == NULL)
return (ERROR);
return (u16_to_str_base_prefix(val, "0123456789", "", out));
}

View file

@ -0,0 +1,51 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* str_to_i64.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */
/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "me/char/char.h"
#include "me/convert/numbers_to_str.h"
#include "me/str/str.h"
#include "me/types.h"
t_error _format_u64(t_num_str args, t_str *out);
t_error u32_to_str_base_prefix(t_u32 val, t_str base, t_str prefix,
t_str *out)
{
union u_nums value;
bool is_nonnegative;
if (out == NULL || base == NULL || prefix == NULL)
return (ERROR);
value.u32 = val;
is_nonnegative = val < 0;
if (is_nonnegative)
value.u32 = ~value.u32 + 1;
return (_format_u64((t_num_str){.value = value.u64, \
.is_nonnegative = is_nonnegative, \
.base = base, \
.prefix = prefix}, \
out));
}
t_error u32_to_str_base(t_u32 val, t_str base, t_str *out)
{
if (out == NULL || base == NULL)
return (ERROR);
return (u32_to_str_base_prefix(val, base, "", out));
}
t_error u32_to_str(t_u32 val, t_str *out)
{
if (out == NULL)
return (ERROR);
return (u32_to_str_base_prefix(val, "0123456789", "", out));
}

View file

@ -0,0 +1,51 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* str_to_i64.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */
/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "me/char/char.h"
#include "me/convert/numbers_to_str.h"
#include "me/str/str.h"
#include "me/types.h"
t_error _format_u64(t_num_str args, t_str *out);
t_error u64_to_str_base_prefix(t_u64 val, t_str base, t_str prefix,
t_str *out)
{
union u_nums value;
bool is_nonnegative;
if (out == NULL || base == NULL || prefix == NULL)
return (ERROR);
value.u64 = val;
is_nonnegative = val < 0;
if (is_nonnegative)
value.u64 = ~value.u64 + 1;
return (_format_u64((t_num_str){.value = value.u64, \
.is_nonnegative = is_nonnegative, \
.base = base, \
.prefix = prefix}, \
out));
}
t_error u64_to_str_base(t_u64 val, t_str base, t_str *out)
{
if (out == NULL || base == NULL)
return (ERROR);
return (u64_to_str_base_prefix(val, base, "", out));
}
t_error u64_to_str(t_u64 val, t_str *out)
{
if (out == NULL)
return (ERROR);
return (u64_to_str_base_prefix(val, "0123456789", "", out));
}

View file

@ -0,0 +1,51 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* str_to_i64.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */
/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "me/char/char.h"
#include "me/convert/numbers_to_str.h"
#include "me/str/str.h"
#include "me/types.h"
t_error _format_u64(t_num_str args, t_str *out);
t_error u8_to_str_base_prefix(t_u8 val, t_str base, t_str prefix,
t_str *out)
{
union u_nums value;
bool is_nonnegative;
if (out == NULL || base == NULL || prefix == NULL)
return (ERROR);
value.u8 = val;
is_nonnegative = val < 0;
if (is_nonnegative)
value.u8 = ~value.u8 + 1;
return (_format_u64((t_num_str){.value = value.u64, \
.is_nonnegative = is_nonnegative, \
.base = base, \
.prefix = prefix}, \
out));
}
t_error u8_to_str_base(t_u8 val, t_str base, t_str *out)
{
if (out == NULL || base == NULL)
return (ERROR);
return (u8_to_str_base_prefix(val, base, "", out));
}
t_error u8_to_str(t_u8 val, t_str *out)
{
if (out == NULL)
return (ERROR);
return (u8_to_str_base_prefix(val, "0123456789", "", out));
}

View file

@ -10,11 +10,8 @@
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "me/mem/mem.h"
#include "me/mem/mem.h"
#include "me/mem/mem.h" #include "me/mem/mem.h"
#include "me/types.h" #include "me/types.h"
#include "me/mem/mem.h"
#include "me/vec/vec_buf_str.h" #include "me/vec/vec_buf_str.h"
#include <stdlib.h> #include <stdlib.h>
@ -45,7 +42,7 @@ t_error vec_buf_str_push(t_vec_buf_str *vec, t_string element)
/// Return true in case of an error /// Return true in case of an error
t_error vec_buf_str_reserve(t_vec_buf_str *vec, t_usize wanted_capacity) t_error vec_buf_str_reserve(t_vec_buf_str *vec, t_usize wanted_capacity)
{ {
size_t new_capacity; size_t new_capacity;
if (vec == NULL) if (vec == NULL)
return (ERROR); return (ERROR);
@ -54,7 +51,8 @@ t_error vec_buf_str_reserve(t_vec_buf_str *vec, t_usize wanted_capacity)
new_capacity = (vec->capacity * 3) / 2 + 1; new_capacity = (vec->capacity * 3) / 2 + 1;
while (wanted_capacity > new_capacity) while (wanted_capacity > new_capacity)
new_capacity = (new_capacity * 3) / 2 + 1; new_capacity = (new_capacity * 3) / 2 + 1;
vec->buffer = mem_realloc_array(vec->buffer, new_capacity, sizeof(t_string)); vec->buffer =
mem_realloc_array(vec->buffer, new_capacity, sizeof(t_string));
vec->capacity = new_capacity; vec->capacity = new_capacity;
} }
return (NO_ERROR); return (NO_ERROR);
@ -83,6 +81,8 @@ t_error vec_buf_str_pop(t_vec_buf_str *vec, t_string *value)
/// This function is safe to call with `free_elem` being NULL /// This function is safe to call with `free_elem` being NULL
void vec_buf_str_free(t_vec_buf_str vec) void vec_buf_str_free(t_vec_buf_str vec)
{ {
if (vec.buffer == NULL)
return;
if (vec.free_func) if (vec.free_func)
{ {
while (vec.len) while (vec.len)

View file

@ -27,7 +27,7 @@ t_error vec_buf_str_find(t_vec_buf_str *vec,
idx = 0; idx = 0;
while (idx < vec->len) while (idx < vec->len)
{ {
if (fn(&vec->buffer[idx])) if (fn((const t_string *)&vec->buffer[idx]))
{ {
*index = idx; *index = idx;
return (NO_ERROR); return (NO_ERROR);
@ -48,7 +48,7 @@ t_error vec_buf_str_find_starting(t_vec_buf_str *vec,
idx = starting_index; idx = starting_index;
while (idx < vec->len) while (idx < vec->len)
{ {
if (fn(&vec->buffer[idx])) if (fn((const t_string *)&vec->buffer[idx]))
{ {
*index = idx; *index = idx;
return (NO_ERROR); return (NO_ERROR);
@ -69,7 +69,7 @@ t_error vec_buf_str_all(t_vec_buf_str *vec,
*result = true; *result = true;
while (*result && idx < vec->len) while (*result && idx < vec->len)
{ {
if (!fn(&vec->buffer[idx])) if (!fn((const t_string *)&vec->buffer[idx]))
*result = false; *result = false;
idx++; idx++;
} }
@ -87,7 +87,7 @@ t_error vec_buf_str_any(t_vec_buf_str *vec,
*result = false; *result = false;
while (*result && idx < vec->len) while (*result && idx < vec->len)
{ {
if (fn(&vec->buffer[idx])) if (fn((const t_string *)&vec->buffer[idx]))
*result = true; *result = true;
idx++; idx++;
} }

View file

@ -10,11 +10,8 @@
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "me/mem/mem.h"
#include "me/mem/mem.h"
#include "me/mem/mem.h" #include "me/mem/mem.h"
#include "me/types.h" #include "me/types.h"
#include "me/mem/mem.h"
#include "me/vec/vec_str.h" #include "me/vec/vec_str.h"
#include <stdlib.h> #include <stdlib.h>
@ -45,7 +42,7 @@ t_error vec_str_push(t_vec_str *vec, t_str element)
/// Return true in case of an error /// Return true in case of an error
t_error vec_str_reserve(t_vec_str *vec, t_usize wanted_capacity) t_error vec_str_reserve(t_vec_str *vec, t_usize wanted_capacity)
{ {
size_t new_capacity; size_t new_capacity;
if (vec == NULL) if (vec == NULL)
return (ERROR); return (ERROR);
@ -54,7 +51,8 @@ t_error vec_str_reserve(t_vec_str *vec, t_usize wanted_capacity)
new_capacity = (vec->capacity * 3) / 2 + 1; new_capacity = (vec->capacity * 3) / 2 + 1;
while (wanted_capacity > new_capacity) while (wanted_capacity > new_capacity)
new_capacity = (new_capacity * 3) / 2 + 1; new_capacity = (new_capacity * 3) / 2 + 1;
vec->buffer = mem_realloc_array(vec->buffer, new_capacity, sizeof(t_str)); vec->buffer =
mem_realloc_array(vec->buffer, new_capacity, sizeof(t_str));
vec->capacity = new_capacity; vec->capacity = new_capacity;
} }
return (NO_ERROR); return (NO_ERROR);
@ -83,6 +81,8 @@ t_error vec_str_pop(t_vec_str *vec, t_str *value)
/// This function is safe to call with `free_elem` being NULL /// This function is safe to call with `free_elem` being NULL
void vec_str_free(t_vec_str vec) void vec_str_free(t_vec_str vec)
{ {
if (vec.buffer == NULL)
return;
if (vec.free_func) if (vec.free_func)
{ {
while (vec.len) while (vec.len)

View file

@ -27,7 +27,7 @@ t_error vec_str_find(t_vec_str *vec,
idx = 0; idx = 0;
while (idx < vec->len) while (idx < vec->len)
{ {
if (fn(&vec->buffer[idx])) if (fn((const t_str *)&vec->buffer[idx]))
{ {
*index = idx; *index = idx;
return (NO_ERROR); return (NO_ERROR);
@ -48,7 +48,7 @@ t_error vec_str_find_starting(t_vec_str *vec,
idx = starting_index; idx = starting_index;
while (idx < vec->len) while (idx < vec->len)
{ {
if (fn(&vec->buffer[idx])) if (fn((const t_str *)&vec->buffer[idx]))
{ {
*index = idx; *index = idx;
return (NO_ERROR); return (NO_ERROR);
@ -69,7 +69,7 @@ t_error vec_str_all(t_vec_str *vec,
*result = true; *result = true;
while (*result && idx < vec->len) while (*result && idx < vec->len)
{ {
if (!fn(&vec->buffer[idx])) if (!fn((const t_str *)&vec->buffer[idx]))
*result = false; *result = false;
idx++; idx++;
} }
@ -87,7 +87,7 @@ t_error vec_str_any(t_vec_str *vec,
*result = false; *result = false;
while (*result && idx < vec->len) while (*result && idx < vec->len)
{ {
if (fn(&vec->buffer[idx])) if (fn((const t_str *)&vec->buffer[idx]))
*result = true; *result = true;
idx++; idx++;
} }

View file

@ -10,11 +10,8 @@
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "me/mem/mem.h"
#include "me/mem/mem.h"
#include "me/mem/mem.h" #include "me/mem/mem.h"
#include "me/types.h" #include "me/types.h"
#include "me/mem/mem.h"
#include "me/vec/vec_u8.h" #include "me/vec/vec_u8.h"
#include <stdlib.h> #include <stdlib.h>
@ -45,7 +42,7 @@ t_error vec_u8_push(t_vec_u8 *vec, t_u8 element)
/// Return true in case of an error /// Return true in case of an error
t_error vec_u8_reserve(t_vec_u8 *vec, t_usize wanted_capacity) t_error vec_u8_reserve(t_vec_u8 *vec, t_usize wanted_capacity)
{ {
size_t new_capacity; size_t new_capacity;
if (vec == NULL) if (vec == NULL)
return (ERROR); return (ERROR);
@ -54,7 +51,8 @@ t_error vec_u8_reserve(t_vec_u8 *vec, t_usize wanted_capacity)
new_capacity = (vec->capacity * 3) / 2 + 1; new_capacity = (vec->capacity * 3) / 2 + 1;
while (wanted_capacity > new_capacity) while (wanted_capacity > new_capacity)
new_capacity = (new_capacity * 3) / 2 + 1; new_capacity = (new_capacity * 3) / 2 + 1;
vec->buffer = mem_realloc_array(vec->buffer, new_capacity, sizeof(t_u8)); vec->buffer =
mem_realloc_array(vec->buffer, new_capacity, sizeof(t_u8));
vec->capacity = new_capacity; vec->capacity = new_capacity;
} }
return (NO_ERROR); return (NO_ERROR);
@ -83,6 +81,8 @@ t_error vec_u8_pop(t_vec_u8 *vec, t_u8 *value)
/// This function is safe to call with `free_elem` being NULL /// This function is safe to call with `free_elem` being NULL
void vec_u8_free(t_vec_u8 vec) void vec_u8_free(t_vec_u8 vec)
{ {
if (vec.buffer == NULL)
return;
if (vec.free_func) if (vec.free_func)
{ {
while (vec.len) while (vec.len)

View file

@ -27,7 +27,7 @@ t_error vec_u8_find(t_vec_u8 *vec,
idx = 0; idx = 0;
while (idx < vec->len) while (idx < vec->len)
{ {
if (fn(&vec->buffer[idx])) if (fn((const t_u8 *)&vec->buffer[idx]))
{ {
*index = idx; *index = idx;
return (NO_ERROR); return (NO_ERROR);
@ -48,7 +48,7 @@ t_error vec_u8_find_starting(t_vec_u8 *vec,
idx = starting_index; idx = starting_index;
while (idx < vec->len) while (idx < vec->len)
{ {
if (fn(&vec->buffer[idx])) if (fn((const t_u8 *)&vec->buffer[idx]))
{ {
*index = idx; *index = idx;
return (NO_ERROR); return (NO_ERROR);
@ -69,7 +69,7 @@ t_error vec_u8_all(t_vec_u8 *vec,
*result = true; *result = true;
while (*result && idx < vec->len) while (*result && idx < vec->len)
{ {
if (!fn(&vec->buffer[idx])) if (!fn((const t_u8 *)&vec->buffer[idx]))
*result = false; *result = false;
idx++; idx++;
} }
@ -87,7 +87,7 @@ t_error vec_u8_any(t_vec_u8 *vec,
*result = false; *result = false;
while (*result && idx < vec->len) while (*result && idx < vec->len)
{ {
if (fn(&vec->buffer[idx])) if (fn((const t_u8 *)&vec->buffer[idx]))
*result = true; *result = true;
idx++; idx++;
} }

View file

@ -27,6 +27,7 @@ char/tolower
char/toupper char/toupper
convert/atoi convert/atoi
convert/itoa convert/itoa
convert/numbers_to_str
fs/close fs/close
fs/fs_internal fs/fs_internal
fs/open fs/open

View file

@ -0,0 +1,99 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* numbers_to_str.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/16 18:15:57 by maiboyer #+# #+# */
/* Updated: 2024/07/16 18:19:42 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "me/convert/numbers_to_str.h"
#include "me/mem/mem.h"
#include "me/str/str.h"
#include "me/types.h"
#include <stdint.h>
static t_error _check_base(t_str base)
{
t_usize i;
t_usize j;
i = 0;
if (base == NULL)
return (ERROR);
while (base[i] != '\0')
{
j = 1;
while (base[i + j] != '\0')
if (base[i + (j++)] == base[i])
return (ERROR);
i++;
}
if (i <= 1)
return (ERROR);
return (NO_ERROR);
}
static void _set_modulus(t_num_str_state *s)
{
s->modulus = 0;
s->base_len = str_len(s->base);
while (UINT64_MAX - s->modulus >= s->base_len)
s->modulus += s->base_len;
}
static char _get_char(t_u64 value, t_num_str_state *s)
{
if (value == 0)
s->zero = true;
else
s->zero = false;
return (s->base[value]);
}
static t_error _format_u64_base_innner(t_num_str_state *s)
{
char c;
if (s->value == 0)
return (s->buffer[s->idx++] = _get_char(0, s), NO_ERROR);
while (s->modulus)
{
c = _get_char(s->value / s->modulus, s);
if (s->zero || s->print)
{
s->buffer[s->idx++] = c;
s->print = true;
}
s->value = s->value % s->modulus;
s->modulus /= s->base_len;
}
return (NO_ERROR);
}
t_error _format_u64(t_num_str args, t_str *out)
{
t_num_str_state s;
t_str res;
if (_check_base(args.base))
return (ERROR);
if (args.prefix == NULL)
args.prefix = "";
mem_set_zero(&s, sizeof(s));
s.idx = 0;
if (args.is_nonnegative)
s.buffer[s.idx++] = '-';
_set_modulus(&s);
s.print = false;
if (_format_u64_base_innner(&s))
return (ERROR);
res = str_join(args.prefix, s.buffer);
if (res == NULL)
return (ERROR);
return (*out = res, NO_ERROR);
}