minishell/stdme/src/printf/formatter/utils.c
2024-05-20 00:35:39 +02:00

137 lines
3.5 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/11/16 17:57:04 by maiboyer #+# #+# */
/* Updated: 2024/05/14 18:43:44 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "me/string/string.h"
#include "me/mem/mem.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/str/str.h"
#include "me/str/str.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);
mem_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;
}