minishell/libft/ft_printf_utils.c
2025-02-12 15:12:42 +01:00

112 lines
2.8 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_printf_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/12/04 10:39:30 by jguelen #+# #+# */
/* Updated: 2024/12/11 14:25:40 by jguelen ### ########.fr */
/* */
/* ************************************************************************** */
#include "ft_printf.h"
/*To handle special printf behaviors regarding strings and precision.*/
static int ft_printf_strlen(char *s, int maxchar)
{
int len;
len = 0;
if (!s)
{
if (maxchar > 5)
return (6);
return (0);
}
while (s[len] && len < maxchar)
len++;
return (len);
}
int ft_int_len(int n, int base_len)
{
int len;
int calc;
len = 0;
calc = n;
if (n == 0)
return (1);
while (calc != 0)
{
calc /= base_len;
len++;
}
return (len);
}
int ft_uint_len(unsigned int n, int base_len)
{
int len;
unsigned int calc;
calc = n;
len = 0;
if (n == 0)
return (1);
while (calc != 0)
{
calc /= base_len;
len++;
}
return (len);
}
/*Naming is a bit off since it can only be used for pointers*/
int ft_ull_len(unsigned long long n, int base_len)
{
unsigned long long calc;
int len;
len = 0;
calc = n;
if (n == 0)
return (ft_strlen("(nil)"));
while (calc != 0)
{
calc /= base_len;
len++;
}
return (len);
}
/*Takes precision into account when relevant.*/
int var_len(t_printf_format *format)
{
t_printf_spec spec;
spec = format->specifier;
if (spec == PRINTF_CHARSPEC || spec == PRINTF_NOSPEC
|| spec == PRINTF_PERCENTSPEC)
return (1);
if (spec == PRINTF_STRINGSPEC)
{
if (format->flags & PRINTF_DOTFLAG)
return (ft_printf_strlen(format->var.s, (int)format->precision));
else
return ((int)ft_printf_strlen(format->var.s, INT_MAX));
}
if (spec == PRINTF_INTSPEC)
return (max_int(ft_int_len(format->var.i, 10), format->precision));
if (spec == PRINTF_UINTSPEC)
return (max_int(ft_uint_len(format->var.u, 10), format->precision));
if (spec == PRINTF_HEXA_LOWSPEC || spec == PRINTF_HEXA_UPSPEC)
return (max_int(ft_uint_len(format->var.u, HEX_LEN),
format->precision));
if (spec == PRINTF_POINTERSPEC)
return (ft_ull_len((unsigned long long)format->var.p, HEX_LEN));
if (ft_isnumeric_conv(format) && !format->var.i && !format->var.u)
return (0);
return (0);
}