--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ft_printf.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2023/08/17 09:14:21 by ljiriste #+# #+# */
+/* Updated: 2023/08/17 16:03:10 by ljiriste ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include <stdlib.h> // malloc, free
+#include <stdarg.h> // va_*
+#include <unistd.h> // write
+#include "libft.h"
+
+int print_ordinary(const char **s)
+{
+ int len;
+
+ len = 0;
+ while ((*s)[len] && (*s)[len] != '%')
+ ++len;
+ write(1, *s, len);
+ *s += len;
+ return (len);
+}
+
+typedef struct s_flags
+{
+ int alt_mode;
+ int zero_pad;
+ int left_adjust;
+ int sign_allign;
+ int sign_show;
+} t_flags;
+
+t_flags parse_flags(const char **format)
+{
+ t_flags flags;
+
+ flags.alt_mode = 0;
+ flags.zero_pad = 0;
+ flags.left_adjust = 0;
+ flags.sign_allign = 0;
+ flags.sign_show = 0;
+ while (true)
+ {
+ if (**format == '#')
+ flags.alt_mode = 1;
+ else if (**format == '0')
+ flags.zero_pad = 1;
+ else if (**format == '-')
+ flags.left_adjust = 1;
+ else if (**format == ' ')
+ flags.sign_allign = 1;
+ else if (**format == '+')
+ flags.sign_show = 1;
+ else
+ return (flags);
+ ++(*format);
+ }
+}
+
+int parse_int(const char **format, va_list *args)
+{
+ int res;
+
+ res = 0;
+ if (**format == '*')
+ {
+ res = va_arg(*args, int);
+ ++(*format);
+ }
+ else if (**format == '-' || ft_isdigit(**format))
+ {
+ res = ft_atoi(*format);
+ while (**format == '-' || ft_isdigit(**format))
+ ++(*format);
+ }
+ return (res);
+}
+
+char *ft_itoa_base(unsigned int n, const char *base, int alt_mode)
+{
+ int size;
+ int base_len;
+ char *res;
+
+ base_len = ft_strlen(base);
+ size = digit_count(n, base_len);
+ if (alt_mode && n != 0)
+ {
+ if (base_len == 8)
+ ++size;
+ else if (base_len == 16)
+ size += 2;
+ }
+ res = malloc(size);
+ if (res == NULL)
+ return (res);
+
+
+#include <limits.h> // for CHAR_BIT - bits in a byte
+#define HEX_BIT = 4 // bits in a hex digit (always 4)
+#define UINT_PTR = sizeof(void *) / sizeof(unsigned int)
+
+char *ptostr(void *p)
+{
+ char *res;
+ char *temp;
+ int i;
+ unsigned int part;
+
+ res = malloc(sizeof(void *) * CHAR_BIT / 4 + 1);
+ if (res == NULL)
+ return (res);
+ i = UINT_PTR;
+ *res = '\0';
+ while (i > 0)
+ {
+ ++i;
+ part = (unsigned int)(p >> (HEX_BIT * i * UINT_PTR));
+ temp = ft_itoa_base(part, "0123456789ABCDEF", 0);
+ if (temp == NULL)
+ {
+ free(res);
+ return (temp);
+ }
+ ft_strlcat(res, temp, sizeof(void *) * CHAR_BIT / 4 + 1);
+ free(temp);
+ }
+ return (res);
+}
+
+char *const_str(const char **format, va_list *args, t_flags flags)
+{
+ char *res;
+
+ res = NULL;
+ if (**format == 'd' || **format == 'i')
+ res = ft_itoa(va_arg(*args, int));
+ else if (**format == 'o')
+ res = ft_itoa_base(va_arg(*args, unsigned int), "01234567", flags.alt_mode);
+ else if (**format == 'u')
+ res = ft_itoa_base(va_arg(*args, unsigned int), "0123456789", 0);
+ else if (**format == 'x')
+ res = ft_itoa_base(va_arg(*args, unsigned int), "0123456789abcdef", flags.alt_mode);
+ else if (**format == 'X')
+ res = ft_itoa_base(va_arg(*args, unsigned int), "0123456789ABCDEF", flags.alt_mode);
+ else if (**format == 'c')
+ {
+ res = malloc(1);
+ if (res)
+ *res = va_arg(*args, char);
+ }
+ else if (**format == 's')
+ res = ft_strdup(va_arg(*args, char *));
+ else if (**format == 'p')
+ res = ptostr(va_arg(*args, void *));
+ return (res);
+}
+
+int handle_conversion(const char **format, va_list *args)
+{
+ t_flags flags;
+ int minwidth;
+ int prec;
+ char *argstr;
+ int len;
+
+ flags = parse_flags(&format);
+ minwidth = parse_int(&format, &args);
+ if (**format == '.')
+ ++(*format);
+ prec = parse_int(&format, &args);
+ argstr = constr_str(&format, &args, flags);
+ len = print_formated(argstr, flags, minwidth, prec);
+ free(argstr);
+ return (len);
+}
+
+int ft_printf(const char *format, ...)
+{
+ va_list args;
+ int res;
+
+ va_start(args, format);
+ while (*format)
+ {
+ res += print_ordinary(&format);
+ if (!*format)
+ break;
+ res += handle_conversion(&format, &args);
+ if (err != 0)
+ {
+ handle_error(err);
+ break;
+ }
+ }
+ va_end(args);
+ return ;
+}