Started from buttom go to the sky
This commit is contained in:
parent
96215449bd
commit
f811e55dea
4781 changed files with 10121 additions and 1743 deletions
70
stdme/src/printf/formatter/char.c
Normal file
70
stdme/src/printf/formatter/char.c
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* char.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/11/18 18:12:11 by maiboyer #+# #+# */
|
||||
/* Updated: 2023/12/11 19:18:48 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/mem/mem_set.h"
|
||||
#include "me/printf/formatter/utils.h"
|
||||
#include "me/printf/printf.h"
|
||||
#include "me/string/str_len.h"
|
||||
#include "me/string/str_substring.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void printf_c(t_printf_arg data, t_printf_func f)
|
||||
{
|
||||
char value[2];
|
||||
t_str start_num;
|
||||
|
||||
value[0] = *(char *)data.argument;
|
||||
value[1] = 0;
|
||||
start_num = &value[0];
|
||||
pad_and_stuff(
|
||||
(t_pad_and_stuff_args){\
|
||||
.fill_zero = 0, .fill = 0, .len = 1, .pretty = "", .pretty_len = 0, \
|
||||
.str = start_num, .allow_zero_fill = false, .sign = NULL, \
|
||||
.sign_len = 0, }, data, f);
|
||||
}
|
||||
|
||||
t_usize printf_s_inner(t_str *value, t_printf_arg *data, t_printf_func *f)
|
||||
{
|
||||
t_usize len;
|
||||
|
||||
if (*value == NULL)
|
||||
{
|
||||
if (data->flags & (PRECISION) && data->extra.precision < 6)
|
||||
*value = "";
|
||||
else
|
||||
*value = "(null)";
|
||||
}
|
||||
len = str_len(*value);
|
||||
if (data->flags & (PRECISION) && len > data->extra.precision)
|
||||
len = data->extra.precision;
|
||||
if (data->flags & (PRECISION) && len < data->extra.precision)
|
||||
data->extra.precision = len;
|
||||
(void)(f);
|
||||
return (len);
|
||||
}
|
||||
|
||||
void printf_s(t_printf_arg data, t_printf_func f)
|
||||
{
|
||||
t_str value;
|
||||
t_str start_num;
|
||||
t_usize len;
|
||||
|
||||
value = (t_str)data.argument;
|
||||
len = printf_s_inner(&value, &data, &f);
|
||||
start_num = str_substring(value, 0, len);
|
||||
pad_and_stuff(
|
||||
(t_pad_and_stuff_args){\
|
||||
.fill_zero = 0, .fill = 0, .len = len, .pretty = "", .pretty_len = 0, \
|
||||
.str = start_num, .allow_zero_fill = false, .sign = NULL, \
|
||||
.sign_len = 0, }, data, f);
|
||||
free(start_num);
|
||||
}
|
||||
89
stdme/src/printf/formatter/decimal.c
Normal file
89
stdme/src/printf/formatter/decimal.c
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* decimal.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maix <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/11/18 01:44:35 by maix #+# #+# */
|
||||
/* Updated: 2023/12/11 19:19:27 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/mem/mem_alloc_array.h"
|
||||
#include "me/mem/mem_set.h"
|
||||
#include "me/printf/formatter/utils.h"
|
||||
#include "me/printf/printf.h"
|
||||
#include "me/string/str_clone.h"
|
||||
#include "me/string/str_len.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define INT_INLINE_BUF 21
|
||||
|
||||
static void itoa_inner(t_u64 nb, t_str out)
|
||||
{
|
||||
t_u64 modulus;
|
||||
bool need_print;
|
||||
char c;
|
||||
t_usize idx;
|
||||
|
||||
need_print = false;
|
||||
modulus = 1000000000000000000;
|
||||
idx = 0;
|
||||
while (modulus)
|
||||
{
|
||||
c = (char)(nb / modulus) + '0';
|
||||
if (c != '0' || need_print)
|
||||
{
|
||||
out[idx++] = c;
|
||||
need_print = true;
|
||||
}
|
||||
nb = nb % modulus;
|
||||
modulus /= 10;
|
||||
}
|
||||
}
|
||||
|
||||
static t_str itoa_64(t_i64 nb)
|
||||
{
|
||||
char out[INT_INLINE_BUF];
|
||||
t_u64 n;
|
||||
|
||||
n = (t_u64)nb;
|
||||
mem_set(out, 0, INT_INLINE_BUF);
|
||||
if (nb < 0)
|
||||
itoa_inner(-n, out);
|
||||
else if (nb == 0)
|
||||
out[0] = '0';
|
||||
else
|
||||
itoa_inner(n, out);
|
||||
return (str_clone(out));
|
||||
}
|
||||
|
||||
void printf_d(t_printf_arg data, t_printf_func f)
|
||||
{
|
||||
t_u64 value;
|
||||
t_str start_num;
|
||||
t_str sign;
|
||||
t_str void_write;
|
||||
|
||||
value = *(t_i64 *)data.argument;
|
||||
if ((t_u64)value & ((t_u64)1 << 31))
|
||||
sign = "-";
|
||||
else
|
||||
sign = "+";
|
||||
if (!(data.flags & SIGN) && !((t_u64)value & ((t_u64)1 << 31)))
|
||||
sign = "";
|
||||
if (!(data.flags & SIGN) && data.extra.space_align
|
||||
&& !((t_u64)value & ((t_u64)1 << 31)))
|
||||
sign = " ";
|
||||
data.flags |= SIGN;
|
||||
start_num = itoa_64(value);
|
||||
handle_weird_precision_stuff(&data, (t_prec_strs){.out = &start_num,
|
||||
.free_out = true, .pretty = &void_write}, value);
|
||||
pad_and_stuff(
|
||||
(t_pad_and_stuff_args){\
|
||||
.fill_zero = 0, .fill = 0, .sign = sign, .pretty = NULL, .len = \
|
||||
str_len(start_num), .pretty_len = 0, .str = start_num, .allow_zero_fill \
|
||||
= true, .sign_len = str_len(sign), }, data, f);
|
||||
free(start_num);
|
||||
}
|
||||
67
stdme/src/printf/formatter/hex.c
Normal file
67
stdme/src/printf/formatter/hex.c
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* hex.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/11/16 18:16:16 by maiboyer #+# #+# */
|
||||
/* Updated: 2023/12/11 19:19:03 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/mem/mem_set.h"
|
||||
#include "me/printf/formatter/utils.h"
|
||||
#include "me/printf/printf.h"
|
||||
#include "me/string/str_len.h"
|
||||
#define HEX_INLINE_BUF 17
|
||||
|
||||
static void fill_hex(t_str out_buf, t_u64 num, t_const_str base)
|
||||
{
|
||||
t_usize i;
|
||||
|
||||
mem_set(out_buf, 0, HEX_INLINE_BUF);
|
||||
out_buf[HEX_INLINE_BUF - 1] = 0;
|
||||
i = 0;
|
||||
while (i < HEX_INLINE_BUF - 1)
|
||||
{
|
||||
out_buf[HEX_INLINE_BUF - i - 2] = base[(num >> (4 * i) & 15)];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static void printf_x_common(t_printf_arg data, t_printf_func f,
|
||||
t_const_str pretty, t_const_str base)
|
||||
{
|
||||
t_u64 value;
|
||||
char inline_buffer[HEX_INLINE_BUF];
|
||||
t_str start_num;
|
||||
|
||||
value = *(t_u64 *)data.argument;
|
||||
inline_buffer[0] = '0';
|
||||
inline_buffer[1] = '\0';
|
||||
if (value)
|
||||
fill_hex(inline_buffer, value, base);
|
||||
start_num = &inline_buffer[0];
|
||||
while (start_num[1] != '\0' && start_num[0] == '0')
|
||||
start_num++;
|
||||
if (value == 0)
|
||||
data.extra.pretty = false;
|
||||
handle_weird_precision_stuff(&data, (t_prec_strs){.out = &start_num,
|
||||
.free_out = false, .pretty = (t_str *)&pretty}, value);
|
||||
pad_and_stuff(
|
||||
(t_pad_and_stuff_args){\
|
||||
.fill_zero = 0, .fill = 0, .len = str_len(start_num), .pretty = (t_str)pretty, \
|
||||
.pretty_len = 2, .str = start_num, .allow_zero_fill = true, .sign = NULL, \
|
||||
.sign_len = 0, }, data, f);
|
||||
}
|
||||
|
||||
void printf_x_up(t_printf_arg data, t_printf_func f)
|
||||
{
|
||||
printf_x_common(data, f, "0X", "0123456789ABCDEF");
|
||||
}
|
||||
|
||||
void printf_x_low(t_printf_arg data, t_printf_func f)
|
||||
{
|
||||
printf_x_common(data, f, "0x", "0123456789abcdef");
|
||||
}
|
||||
60
stdme/src/printf/formatter/oct.c
Normal file
60
stdme/src/printf/formatter/oct.c
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* oct.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maix <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/11/18 01:19:18 by maix #+# #+# */
|
||||
/* Updated: 2023/12/11 19:17:23 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/mem/mem_set.h"
|
||||
#include "me/printf/formatter/utils.h"
|
||||
#include "me/printf/printf.h"
|
||||
#include "me/string/str_len.h"
|
||||
#include <stdio.h>
|
||||
#define OCT_INLINE_BUF 23
|
||||
|
||||
static void fill_oct(t_str out_buf, t_u64 num, t_str base)
|
||||
{
|
||||
t_usize i;
|
||||
|
||||
mem_set(out_buf, 0, OCT_INLINE_BUF);
|
||||
out_buf[OCT_INLINE_BUF - 1] = 0;
|
||||
i = 0;
|
||||
while (i < OCT_INLINE_BUF - 1)
|
||||
{
|
||||
out_buf[OCT_INLINE_BUF - i - 2] = base[(num >> (3 * i) & 7)];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void printf_o(t_printf_arg data, t_printf_func f)
|
||||
{
|
||||
t_u64 value;
|
||||
char inline_buffer[OCT_INLINE_BUF];
|
||||
t_str start_num;
|
||||
t_str pretty;
|
||||
|
||||
value = *(t_u64 *)data.argument;
|
||||
inline_buffer[0] = '0';
|
||||
inline_buffer[1] = '\0';
|
||||
pretty = "0o";
|
||||
if (value)
|
||||
fill_oct(inline_buffer, value, "01234567");
|
||||
start_num = &inline_buffer[0];
|
||||
while (start_num[1] != '\0' && start_num[0] == '0')
|
||||
start_num++;
|
||||
if (!value && data.extra.precision == 0 && (data.flags & PRECISION))
|
||||
{
|
||||
start_num = "";
|
||||
pretty = "";
|
||||
}
|
||||
pad_and_stuff(
|
||||
(t_pad_and_stuff_args){\
|
||||
.fill_zero = 0, .fill = 0, .len = str_len(start_num), .pretty = pretty, \
|
||||
.pretty_len = str_len(pretty), .str = start_num, .allow_zero_fill = true, \
|
||||
.sign = NULL, .sign_len = 0, }, data, f);
|
||||
}
|
||||
74
stdme/src/printf/formatter/ptr.c
Normal file
74
stdme/src/printf/formatter/ptr.c
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* ptr.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/11/16 18:16:16 by maiboyer #+# #+# */
|
||||
/* Updated: 2023/12/11 19:20:42 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/mem/mem_set.h"
|
||||
#include "me/printf/formatter/utils.h"
|
||||
#include "me/printf/printf.h"
|
||||
#include "me/string/str_len.h"
|
||||
#define PTR_INLINE_BUF 17
|
||||
|
||||
static void fill_hex(t_str out_buf, t_u64 num, t_str base)
|
||||
{
|
||||
t_usize i;
|
||||
|
||||
mem_set(out_buf, 0, PTR_INLINE_BUF);
|
||||
out_buf[PTR_INLINE_BUF - 1] = 0;
|
||||
i = 0;
|
||||
while (i < PTR_INLINE_BUF - 1)
|
||||
{
|
||||
out_buf[PTR_INLINE_BUF - i - 2] = base[(num >> (4 * i) & 15)];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_values_for_nil(t_usize value, t_str *out, t_printf_arg *data,
|
||||
t_printf_func f)
|
||||
{
|
||||
(void)(f);
|
||||
if (value)
|
||||
{
|
||||
data->flags &= ~PRECISION;
|
||||
data->extra.precision = 0;
|
||||
data->extra.pretty = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
*out = "(nil)";
|
||||
data->extra.precision = 0;
|
||||
data->extra.pretty = false;
|
||||
data->flags &= ~(ZERO_ALIGN | PRECISION);
|
||||
data->flags |= ALIGN;
|
||||
}
|
||||
}
|
||||
|
||||
void printf_p(t_printf_arg data, t_printf_func f)
|
||||
{
|
||||
t_u64 value;
|
||||
char inline_buffer[PTR_INLINE_BUF + 1];
|
||||
t_str start_num;
|
||||
|
||||
value = (t_u64)data.argument;
|
||||
inline_buffer[0] = '0';
|
||||
inline_buffer[1] = '\0';
|
||||
if (value)
|
||||
fill_hex(inline_buffer, value, "0123456789abcdef");
|
||||
start_num = &inline_buffer[0];
|
||||
inline_buffer[PTR_INLINE_BUF] = 0;
|
||||
while (start_num[1] != '\0' && start_num[0] == '0')
|
||||
start_num++;
|
||||
set_values_for_nil(value, &start_num, &data, f);
|
||||
pad_and_stuff(
|
||||
(t_pad_and_stuff_args){\
|
||||
.fill_zero = 0, .fill = 0, .len = str_len(start_num), .pretty = "0x", \
|
||||
.pretty_len = 2, .str = start_num, .allow_zero_fill = value != 0, \
|
||||
.sign = NULL, .sign_len = 0, }, data, f);
|
||||
}
|
||||
76
stdme/src/printf/formatter/unsigned_decimal.c
Normal file
76
stdme/src/printf/formatter/unsigned_decimal.c
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* unsigned_decimal.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maix <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/11/18 01:44:35 by maix #+# #+# */
|
||||
/* Updated: 2023/12/11 19:19:59 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/mem/mem_alloc_array.h"
|
||||
#include "me/mem/mem_set.h"
|
||||
#include "me/printf/formatter/utils.h"
|
||||
#include "me/printf/printf.h"
|
||||
#include "me/string/str_clone.h"
|
||||
#include "me/string/str_len.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define UINT_INLINE_BUF 21
|
||||
|
||||
static void itoa_inner(t_u64 nb, t_str out)
|
||||
{
|
||||
t_u64 modulus;
|
||||
bool need_print;
|
||||
char c;
|
||||
t_usize idx;
|
||||
|
||||
need_print = false;
|
||||
modulus = 10000000000000000000u;
|
||||
idx = 0;
|
||||
while (modulus)
|
||||
{
|
||||
c = (char)(nb / modulus) + '0';
|
||||
if (c != '0' || need_print)
|
||||
{
|
||||
out[idx++] = c;
|
||||
need_print = true;
|
||||
}
|
||||
nb = nb % modulus;
|
||||
modulus /= 10;
|
||||
}
|
||||
}
|
||||
|
||||
static t_str itoa_u64(t_u64 nb)
|
||||
{
|
||||
char out[UINT_INLINE_BUF];
|
||||
t_u64 n;
|
||||
|
||||
n = (t_u64)nb;
|
||||
mem_set(out, 0, UINT_INLINE_BUF);
|
||||
if (nb == 0)
|
||||
out[0] = '0';
|
||||
else
|
||||
itoa_inner(n, out);
|
||||
return (str_clone(out));
|
||||
}
|
||||
|
||||
void printf_u(t_printf_arg data, t_printf_func f)
|
||||
{
|
||||
t_u64 value;
|
||||
t_str start_num;
|
||||
t_str void_write;
|
||||
|
||||
value = *(t_u64 *)data.argument;
|
||||
start_num = itoa_u64(value);
|
||||
handle_weird_precision_stuff(&data, (t_prec_strs){.out = &start_num,
|
||||
.free_out = true, .pretty = &void_write}, value);
|
||||
pad_and_stuff(
|
||||
(t_pad_and_stuff_args){\
|
||||
.fill_zero = 0, .fill = 0, .len = str_len(start_num), \
|
||||
.pretty = NULL, .pretty_len = 0, .str = start_num, \
|
||||
.allow_zero_fill = true, .sign = NULL, .sign_len = 0, }, data, f);
|
||||
free(start_num);
|
||||
}
|
||||
136
stdme/src/printf/formatter/utils.c
Normal file
136
stdme/src/printf/formatter/utils.c
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* utils.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/11/16 17:57:04 by maiboyer #+# #+# */
|
||||
/* Updated: 2023/12/01 21:20:07 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/buffered_str/buf_str.h"
|
||||
#include "me/convert/atoi.h"
|
||||
#include "me/printf/formatter/utils.h"
|
||||
#include "me/printf/matchers/matchers.h"
|
||||
#include "me/printf/printf.h"
|
||||
#include "me/string/str_find_chr.h"
|
||||
#include "me/string/str_substring.h"
|
||||
#include "me/types.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
bool handle_atoi_stuff(t_const_str fmt, t_usize *c_idx, t_usize *nxt,
|
||||
t_printf_arg *c_arg)
|
||||
{
|
||||
t_i32 atoi_res;
|
||||
|
||||
atoi_res = me_atoi(&fmt[*c_idx]);
|
||||
if (atoi_res < 0)
|
||||
{
|
||||
*c_idx = *nxt;
|
||||
*nxt = (t_usize)(str_find_chr(fmt + *nxt + 1, '%') - fmt);
|
||||
return (false);
|
||||
}
|
||||
advance_atoi(fmt, c_idx);
|
||||
c_arg->extra.align = (t_u64)atoi_res;
|
||||
handle_prec_and_align(fmt, c_idx, c_arg);
|
||||
atoi_res = atoi(&fmt[*c_idx]);
|
||||
if (atoi_res < 0)
|
||||
{
|
||||
*c_idx = *nxt;
|
||||
*nxt = (t_usize)(str_find_chr(fmt + *nxt + 1, '%') - fmt);
|
||||
return (false);
|
||||
}
|
||||
advance_atoi(fmt, c_idx);
|
||||
c_arg->extra.precision = (t_u64)atoi_res;
|
||||
return (true);
|
||||
}
|
||||
|
||||
static void set_flags_if_needed(t_const_str fmt, t_usize *c_idx,
|
||||
t_printf_arg *c_arg)
|
||||
{
|
||||
if (fmt[*c_idx] == ' ')
|
||||
{
|
||||
(*c_idx)++;
|
||||
c_arg->extra.space_align = true;
|
||||
}
|
||||
if (fmt[*c_idx] == '#')
|
||||
{
|
||||
(*c_idx)++;
|
||||
c_arg->extra.pretty = true;
|
||||
}
|
||||
if (fmt[*c_idx] == '+')
|
||||
{
|
||||
(*c_idx)++;
|
||||
c_arg->flags |= SIGN;
|
||||
}
|
||||
if (fmt[*c_idx] == '-')
|
||||
{
|
||||
(*c_idx)++;
|
||||
c_arg->extra.left_align = true;
|
||||
}
|
||||
if (fmt[*c_idx] == '0')
|
||||
{
|
||||
(*c_idx)++;
|
||||
c_arg->flags |= ZERO_ALIGN;
|
||||
}
|
||||
}
|
||||
|
||||
bool set_params(t_const_str fmt, t_usize *c_idx, t_usize *nxt,
|
||||
t_printf_arg *c_arg)
|
||||
{
|
||||
t_usize b_idx;
|
||||
|
||||
b_idx = ~0;
|
||||
while (b_idx != *c_idx)
|
||||
{
|
||||
b_idx = *c_idx;
|
||||
set_flags_if_needed(fmt, c_idx, c_arg);
|
||||
}
|
||||
return (handle_atoi_stuff(fmt, c_idx, nxt, c_arg));
|
||||
}
|
||||
|
||||
t_printf_arg print_substr(t_usize *c_idx, t_usize *nxt, t_const_str fmt,
|
||||
t_pad_inner_args extra)
|
||||
{
|
||||
t_str truc;
|
||||
|
||||
truc = str_substring(fmt, *c_idx, *nxt - *c_idx);
|
||||
extra.f(truc, *nxt - *c_idx, extra.p_args);
|
||||
free(truc);
|
||||
*c_idx = *nxt + 1;
|
||||
return ((t_printf_arg){
|
||||
.p_args = extra.p_args,
|
||||
.argument = extra.arguments,
|
||||
});
|
||||
}
|
||||
|
||||
void pad_inner(t_const_str fmt, t_usize *c_idx, t_usize *nxt,
|
||||
t_pad_inner_args extra)
|
||||
{
|
||||
t_printf_arg c_arg;
|
||||
t_matcher *matcher;
|
||||
|
||||
c_arg = print_substr(c_idx, nxt, fmt, extra);
|
||||
if (fmt[*c_idx] == '%')
|
||||
{
|
||||
(*c_idx)++;
|
||||
extra.f("%", 1, extra.p_args);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!set_params(fmt, c_idx, nxt, &c_arg))
|
||||
return (ret_reset(c_idx, nxt, fmt));
|
||||
matcher = find_matcher(fmt, extra.matchers, c_idx);
|
||||
if (matcher == NULL)
|
||||
return (ret_reset(c_idx, nxt, fmt));
|
||||
call_matcher(matcher, c_arg, *extra.arguments, extra.f);
|
||||
}
|
||||
*nxt = (t_usize)(str_find_chr(fmt + *c_idx, '%'));
|
||||
if (*nxt == 0)
|
||||
return (*nxt = extra.fmt_len, (void)extra.f(fmt + *c_idx, extra.fmt_len
|
||||
- *c_idx, extra.p_args));
|
||||
*nxt = *nxt - (t_usize)fmt;
|
||||
}
|
||||
96
stdme/src/printf/formatter/utils2.c
Normal file
96
stdme/src/printf/formatter/utils2.c
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* utils2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/11/16 18:00:07 by maiboyer #+# #+# */
|
||||
/* Updated: 2023/12/01 21:48:22 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/buffered_str/buf_str.h"
|
||||
#include "me/char/isdigit.h"
|
||||
#include "me/printf/formatter/utils.h"
|
||||
#include "me/printf/printf.h"
|
||||
#include "me/types.h"
|
||||
|
||||
void set_var_for_pad_and_stuff(t_pad_and_stuff_args *a, t_printf_arg *d)
|
||||
{
|
||||
t_isize fill_zero;
|
||||
t_isize fill;
|
||||
|
||||
fill_zero = 0;
|
||||
fill = 0;
|
||||
if (d->flags & ZERO_ALIGN && a->len < d->extra.align)
|
||||
fill_zero = d->extra.align - a->len - a->fill_zero - 2 * d->extra.pretty
|
||||
- a->sign_len;
|
||||
if (d->flags & PRECISION && a->len < d->extra.precision)
|
||||
fill_zero = d->extra.precision - a->len;
|
||||
if (d->flags & (ALIGN) && a->len < d->extra.align)
|
||||
fill = d->extra.align - a->len - a->fill_zero - 2 * d->extra.pretty
|
||||
- a->sign_len - fill_zero;
|
||||
if (fill_zero < 0)
|
||||
fill_zero = 0;
|
||||
if (fill < 0)
|
||||
fill = 0;
|
||||
if (fill_zero < 0)
|
||||
fill_zero = 0;
|
||||
if (fill < 0)
|
||||
fill = 0;
|
||||
a->fill_zero = fill_zero;
|
||||
a->fill = fill;
|
||||
}
|
||||
|
||||
void print_with_func(t_pad_and_stuff_args *a, t_printf_arg *d,
|
||||
t_printf_func f, t_const_str t)
|
||||
{
|
||||
f(t, 1, d->p_args);
|
||||
if (t[0] == ' ' && t[1] == 0 && a->fill)
|
||||
a->fill--;
|
||||
if (t[0] == '0' && t[1] == 0 && a->fill_zero)
|
||||
a->fill_zero--;
|
||||
}
|
||||
|
||||
void pad_and_stuff(t_pad_and_stuff_args a, t_printf_arg d, t_printf_func f)
|
||||
{
|
||||
set_var_for_pad_and_stuff(&a, &d);
|
||||
if (!(d.extra.left_align || d.extra.precision) && d.flags & (ZERO_ALIGN))
|
||||
{
|
||||
print_sign_if_needed(a, d, f);
|
||||
while (a.allow_zero_fill && a.fill_zero > 0)
|
||||
print_with_func(&a, &d, f, "0");
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!(d.extra.left_align) && d.flags & (ALIGN) && a.fill > 0)
|
||||
print_with_func(&a, &d, f, " ");
|
||||
print_sign_if_needed(a, d, f);
|
||||
if (d.extra.pretty)
|
||||
f(a.pretty, a.pretty_len, d.p_args);
|
||||
}
|
||||
while (a.allow_zero_fill && a.fill_zero > 0)
|
||||
print_with_func(&a, &d, f, "0");
|
||||
f(a.str, a.len, d.p_args);
|
||||
while (d.extra.left_align && a.fill > 0)
|
||||
print_with_func(&a, &d, f, " ");
|
||||
}
|
||||
|
||||
void handle_prec_and_align(t_const_str fmt, t_usize *c_idx,
|
||||
t_printf_arg *c_arg)
|
||||
{
|
||||
if (c_arg->extra.align && !(c_arg->flags & ZERO_ALIGN))
|
||||
c_arg->flags |= ALIGN;
|
||||
if (fmt[*c_idx] == '.')
|
||||
{
|
||||
(*c_idx)++;
|
||||
c_arg->flags |= PRECISION;
|
||||
}
|
||||
}
|
||||
|
||||
void advance_atoi(t_const_str fmt, t_usize *idx)
|
||||
{
|
||||
while (me_isdigit(fmt[*idx]))
|
||||
(*idx)++;
|
||||
}
|
||||
53
stdme/src/printf/formatter/utils3.c
Normal file
53
stdme/src/printf/formatter/utils3.c
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* utils3.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/11/16 18:06:15 by maiboyer #+# #+# */
|
||||
/* Updated: 2023/12/11 19:21:38 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/printf/formatter/utils.h"
|
||||
#include "me/printf/matchers/matchers.h"
|
||||
#include "me/string/str_find_chr.h"
|
||||
#include "me/string/str_len.h"
|
||||
#include "me/types.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void ret_reset(t_usize *c_idx, t_usize *nxt, t_const_str fmt)
|
||||
{
|
||||
*c_idx = *nxt;
|
||||
*nxt = (t_usize)(str_find_chr(fmt + *nxt + 1, '%') - fmt);
|
||||
}
|
||||
|
||||
void me_printf_str_inner(t_const_str fmt, t_printf_func f,
|
||||
va_list *arguments, void *p_args)
|
||||
{
|
||||
t_usize c_idx;
|
||||
t_usize nxt;
|
||||
t_usize fmt_len;
|
||||
|
||||
c_idx = 0;
|
||||
fmt_len = str_len(fmt);
|
||||
nxt = (t_usize)(str_find_chr(fmt, '%'));
|
||||
if (nxt == 0)
|
||||
return (f(fmt, fmt_len, p_args));
|
||||
nxt = nxt - (t_usize)fmt;
|
||||
while (nxt < fmt_len)
|
||||
{
|
||||
pad_inner(fmt, &c_idx, &nxt, \
|
||||
((t_pad_inner_args){\
|
||||
.p_args = p_args, .fmt_len = fmt_len, .f = f, \
|
||||
.arguments = arguments, .matchers = get_matchers(), }));
|
||||
}
|
||||
}
|
||||
|
||||
void print_sign_if_needed(t_pad_and_stuff_args a, t_printf_arg d,
|
||||
t_printf_func f)
|
||||
{
|
||||
if (d.flags & (SIGN) && a.sign != NULL)
|
||||
f(a.sign, a.sign_len, d.p_args);
|
||||
}
|
||||
36
stdme/src/printf/formatter/utils_numbers.c
Normal file
36
stdme/src/printf/formatter/utils_numbers.c
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* utils_numbers.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/12/01 21:05:47 by maiboyer #+# #+# */
|
||||
/* Updated: 2023/12/01 21:49:51 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/mem/mem_alloc_array.h"
|
||||
#include "me/printf/formatter/utils.h"
|
||||
#include "me/printf/printf.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void handle_weird_precision_stuff(t_printf_arg *data, t_prec_strs strs,
|
||||
t_usize value)
|
||||
{
|
||||
if (!value && data->extra.precision == 0 && (data->flags & PRECISION))
|
||||
{
|
||||
data->flags &= (~ZERO_ALIGN);
|
||||
data->flags |= ALIGN;
|
||||
if (strs.free_out)
|
||||
*strs.out = (free(*strs.out), (t_str)mem_alloc_array(1, 1));
|
||||
else
|
||||
*strs.out = "";
|
||||
*strs.pretty = "";
|
||||
}
|
||||
else if ((data->flags & PRECISION) && !data->extra.left_align)
|
||||
{
|
||||
data->flags &= (~ZERO_ALIGN);
|
||||
data->flags |= ALIGN;
|
||||
}
|
||||
}
|
||||
120
stdme/src/printf/matchers.c
Normal file
120
stdme/src/printf/matchers.c
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* matchers.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/11/16 18:07:40 by maiboyer #+# #+# */
|
||||
/* Updated: 2023/12/11 19:11:51 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/mem/mem_compare.h"
|
||||
#include "me/printf/formatter/formatter.h"
|
||||
#include "me/printf/matchers/matchers.h"
|
||||
#include "me/printf/printf.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
t_matcher_list *get_matchers(void)
|
||||
{
|
||||
static t_matcher_list printf_matchers = (t_matcher_list){
|
||||
.data = {
|
||||
{.matcher = "o", .matcher_len = 1, .arg_type = U64, .f = &printf_o},
|
||||
{.matcher = "c", .matcher_len = 1, .arg_type = CHAR, .f = &printf_c},
|
||||
{.matcher = "s", .matcher_len = 1, .arg_type = STR, .f = &printf_s},
|
||||
{.matcher = "p", .matcher_len = 1, .arg_type = VOID_PTR, .f = &printf_p},
|
||||
{.matcher = "d", .matcher_len = 1, .arg_type = I32, .f = &printf_d},
|
||||
{.matcher = "i", .matcher_len = 1, .arg_type = I32, .f = &printf_d},
|
||||
{.matcher = "u", .matcher_len = 1, .arg_type = U32, .f = &printf_u},
|
||||
{.matcher = "x", .matcher_len = 1, .arg_type = U32, .f = &printf_x_low},
|
||||
{.matcher = "X", .matcher_len = 1, .arg_type = U32, .f = &printf_x_up},
|
||||
},
|
||||
.next = NULL,
|
||||
};
|
||||
|
||||
return (&printf_matchers);
|
||||
}
|
||||
|
||||
bool insert_matcher(t_matcher matcher)
|
||||
{
|
||||
t_matcher_list *matchers;
|
||||
t_usize i;
|
||||
|
||||
matchers = get_matchers();
|
||||
while (matchers)
|
||||
{
|
||||
i = 0;
|
||||
while (i < PRINTF_BUFFER_CHUNK)
|
||||
{
|
||||
if (matchers->data[i].f == NULL)
|
||||
{
|
||||
(*matchers).data[i] = matcher;
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
matchers->next = malloc(sizeof(t_matcher_list) * 1);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
t_matcher *find_matcher(t_const_str fmt, t_matcher_list *matchers,
|
||||
t_usize *c_idx)
|
||||
{
|
||||
t_usize matcher_index;
|
||||
t_matcher *matcher;
|
||||
|
||||
while (matchers)
|
||||
{
|
||||
matcher_index = 0;
|
||||
while (matcher_index < PRINTF_BUFFER_CHUNK)
|
||||
{
|
||||
matcher = &matchers->data[matcher_index];
|
||||
if (matcher->f)
|
||||
{
|
||||
if (!mem_compare(&fmt[*c_idx], matcher->matcher,
|
||||
matcher->matcher_len))
|
||||
{
|
||||
*c_idx += matcher->matcher_len;
|
||||
return (matcher);
|
||||
}
|
||||
}
|
||||
matcher_index++;
|
||||
}
|
||||
matchers = matchers->next;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// FIGURE OUT HOW TO MAKE I64 WORK
|
||||
void call_matcher(t_matcher *matcher, t_printf_arg matcher_arguments,
|
||||
va_list args, t_printf_func f)
|
||||
{
|
||||
t_matcher_tmp_val vals;
|
||||
|
||||
matcher_arguments.argument = NULL;
|
||||
if (matcher->arg_type == CHAR)
|
||||
{
|
||||
vals.chr_val = (char)va_arg(args, int);
|
||||
matcher_arguments.argument = (void *)&vals.chr_val;
|
||||
}
|
||||
if (matcher->arg_type == U32)
|
||||
vals.u64_val = va_arg(args, t_u32);
|
||||
if (matcher->arg_type == U64)
|
||||
vals.u64_val = va_arg(args, t_u64);
|
||||
if (matcher->arg_type == I64)
|
||||
vals.i64_val = va_arg(args, t_i64);
|
||||
if (matcher->arg_type == I32)
|
||||
vals.i64_val = va_arg(args, t_i32);
|
||||
if (matcher->arg_type == I32 || matcher->arg_type == I64)
|
||||
matcher_arguments.argument = (void *)&vals.i64_val;
|
||||
if (matcher->arg_type == U32 || matcher->arg_type == U64)
|
||||
matcher_arguments.argument = (void *)&vals.u64_val;
|
||||
if (matcher->arg_type == VOID_PTR)
|
||||
matcher_arguments.argument = (void *)va_arg(args, void *);
|
||||
if (matcher->arg_type == STR)
|
||||
matcher_arguments.argument = (void *)va_arg(args, t_str);
|
||||
matcher->f(matcher_arguments, f);
|
||||
}
|
||||
120
stdme/src/printf/printf.c
Normal file
120
stdme/src/printf/printf.c
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* printf.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/11/11 17:50:56 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/02/09 14:58:10 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/buffered_str/buf_str.h"
|
||||
#include "me/fs/write.h"
|
||||
#include "me/printf/formatter/formatter.h"
|
||||
#include "me/printf/formatter/utils.h"
|
||||
#include "me/printf/matchers/matchers.h"
|
||||
#include "me/printf/printf.h"
|
||||
#include "me/string/str_len.h"
|
||||
#include "me/types.h"
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// p_args is an t_buffer_str;
|
||||
static void me_printf_add_to_string(t_const_str to_write, t_usize to_write_len,
|
||||
void *p_args)
|
||||
{
|
||||
t_buffer_str *out_buf;
|
||||
|
||||
out_buf = (t_buffer_str *)p_args;
|
||||
(void)(to_write_len);
|
||||
push_str_buffer(out_buf, to_write);
|
||||
}
|
||||
|
||||
t_str me_printf_str(t_const_str fmt, va_list *arguments)
|
||||
{
|
||||
t_buffer_str out;
|
||||
|
||||
out = alloc_new_buffer(str_len(fmt));
|
||||
if (out.buf == NULL)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
me_printf_str_inner(fmt, &me_printf_add_to_string, arguments, (void *)&out);
|
||||
return (out.buf);
|
||||
}
|
||||
|
||||
void me_printf_write(t_const_str to_write, t_usize to_write_len,
|
||||
void *p_args)
|
||||
{
|
||||
t_fprintf_arg *arg;
|
||||
|
||||
arg = (t_fprintf_arg *)p_args;
|
||||
me_write(arg->fd, (t_u8 *)to_write, to_write_len);
|
||||
arg->total_print += to_write_len;
|
||||
}
|
||||
|
||||
t_usize me_printf(t_const_str fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
t_fprintf_arg passthru;
|
||||
|
||||
passthru = (t_fprintf_arg){
|
||||
.fd = 1,
|
||||
.total_print = 0,
|
||||
};
|
||||
va_start(args, fmt);
|
||||
me_printf_str_inner(fmt, &me_printf_write, &args, (void *)&passthru);
|
||||
va_end(args);
|
||||
return (passthru.total_print);
|
||||
}
|
||||
|
||||
t_usize me_eprintf(t_const_str fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
t_fprintf_arg passthru;
|
||||
|
||||
passthru = (t_fprintf_arg){
|
||||
.fd = 2,
|
||||
.total_print = 0,
|
||||
};
|
||||
va_start(args, fmt);
|
||||
me_printf_str_inner(fmt, &me_printf_write, &args, (void *)&passthru);
|
||||
va_end(args);
|
||||
return (passthru.total_print);
|
||||
}
|
||||
|
||||
/*
|
||||
t_usize me_printf(t_const_str fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
t_str str;
|
||||
t_usize len;
|
||||
|
||||
va_start(args, fmt);
|
||||
str = me_printf_str(fmt, &args);
|
||||
va_end(args);
|
||||
len = str_len(str);
|
||||
write(1, str, len);
|
||||
free(str);
|
||||
return (len);
|
||||
}
|
||||
|
||||
t_usize me_eprintf(t_const_str fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
t_str str;
|
||||
t_usize len;
|
||||
|
||||
va_start(args, fmt);
|
||||
str = me_printf_str(fmt, &args);
|
||||
va_end(args);
|
||||
len = str_len(str);
|
||||
write(2, str, len);
|
||||
free(str);
|
||||
return (len);
|
||||
}
|
||||
*/
|
||||
51
stdme/src/printf/vprintf.c
Normal file
51
stdme/src/printf/vprintf.c
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vprintf.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/02/09 14:57:28 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/02/09 15:00:39 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/buffered_str/buf_str.h"
|
||||
#include "me/fs/write.h"
|
||||
#include "me/printf/formatter/formatter.h"
|
||||
#include "me/printf/formatter/utils.h"
|
||||
#include "me/printf/matchers/matchers.h"
|
||||
#include "me/printf/printf.h"
|
||||
#include "me/string/str_len.h"
|
||||
#include "me/types.h"
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void me_printf_write(t_const_str to_write, t_usize to_write_len,
|
||||
void *p_args);
|
||||
|
||||
t_usize me_vprintf(t_const_str fmt, va_list *args)
|
||||
{
|
||||
t_fprintf_arg passthru;
|
||||
|
||||
passthru = (t_fprintf_arg){
|
||||
.fd = 1,
|
||||
.total_print = 0,
|
||||
};
|
||||
me_printf_str_inner(fmt, &me_printf_write, args, (void *)&passthru);
|
||||
return (passthru.total_print);
|
||||
}
|
||||
|
||||
t_usize me_veprintf(t_const_str fmt, va_list *args)
|
||||
{
|
||||
t_fprintf_arg passthru;
|
||||
|
||||
passthru = (t_fprintf_arg){
|
||||
.fd = 2,
|
||||
.total_print = 0,
|
||||
};
|
||||
me_printf_str_inner(fmt, &me_printf_write, args, (void *)&passthru);
|
||||
return (passthru.total_print);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue