Everything is broken, so I'm committing changes to ft_printf so I don't have to worry...
authorLukas Jiriste <ljiriste@student.42prague.com>
Thu, 24 Aug 2023 07:03:44 +0000 (09:03 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Thu, 24 Aug 2023 07:03:44 +0000 (09:03 +0200)
(Changed author as I haven't set author and a default was used)

ft_printf.c

index 3b03617bf83ccfd73f3c626d4f53a8cd69c4246d..9946fb097d690fc73fb4afe0776de67abfe8b6d3 100644 (file)
@@ -27,7 +27,7 @@ int   print_ordinary(const char **s)
        return (len);
 }
 
-typedef struct s_flags
+typedef        struct s_flags
 {
        int     alt_mode;
        int     zero_pad;
@@ -36,6 +36,14 @@ typedef struct s_flags
        int     sign_show;
 }              t_flags;
 
+typedef        struct s_conv
+{
+       t_flags flags;
+       int             minwidth;
+       int             prec;
+       char    type;
+}                      t_conv;
+
 t_flags        parse_flags(const char **format)
 {
        t_flags flags;
@@ -45,7 +53,7 @@ t_flags       parse_flags(const char **format)
        flags.left_adjust = 0;
        flags.sign_allign = 0;
        flags.sign_show = 0;    
-       while (true)
+       while (1)
        {
                if (**format == '#')
                        flags.alt_mode = 1;
@@ -82,102 +90,208 @@ int       parse_int(const char **format, va_list *args)
        return (res);
 }
 
-char   *ft_itoa_base(unsigned int n, const char *base, int alt_mode)
+#include <stdint.h>
+
+int    size_needed(intptr_t n, size_t base_len)
+{
+       int     res;
+
+       if (n == 0)
+               return (2);
+       res = 1;
+       if (n < 0)
+               ++res;
+       while (n != 0)
+       {
+               ++res;
+               n /= base_len;
+       }
+       return (res);
+}
+
+int    valid_base(const char *base)
+{
+       int     i;
+       int     j;
+
+       if (ft_strlen(base) < 2)
+               return (0);
+       i = 0;
+       while (base[i])
+       {
+               j = i + 1;
+               while (base[j])
+                       if (base[i] == base[j++])
+                               return (0);
+               ++i;
+       }
+       return (1);
+}
+
+
+char   *ft_itoa_base(intptr_t n, const char *base)
 {
        int             size;
-       int             base_len;
+       size_t  base_len;
        char    *res;
 
+       if (!valid_base(base))
+               return (NULL);
        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;
-       }
+       size = size_needed(n, base_len);
        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)
+       if (n < 0)
+               res[0] = '-';
+       res[size--] = '\0';
+       while (n != 0)
+       {
+               res[size--] = base[abs(n % base_len)];
+               n /= base_len;
+       }
+       return (res);
+}
 
-char   *ptostr(void *p)
+char   *ft_ctoa(char c)
 {
-       char                    *res;
-       char                    *temp;
-       int                             i;
-       unsigned int    part;
+       char    *res;
 
-       res = malloc(sizeof(void *) * CHAR_BIT / 4 + 1);
+       res = malloc(2 * sizeof(char));
        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);
-       }
+       res[0] = c;
+       res[1] = '\0';
        return (res);
 }
 
-char   *const_str(const char **format, va_list *args, t_flags flags)
+char   *base_str_constr(char type, va_list *args)
 {
        char    *res;
 
        res = NULL;
-       if (**format == 'd' || **format == 'i')
+       if (type == 'd' || type == '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')
+       else if (type == 'o')
+               res = ft_itoa_base(va_arg(*args, unsigned int), "01234567");
+       else if (type == 'u')
+               res = ft_itoa_base(va_arg(*args, unsigned int), "0123456789");
+       else if (type == 'x')
+               res = ft_itoa_base(va_arg(*args, unsigned int), "0123456789abcdef");
+       else if (type == 'X')
+               res = ft_itoa_base(va_arg(*args, unsigned int), "0123456789ABCDEF");
+       else if (type == 'c')
+               res = ft_ctoa(va_arg(*args, int));
+       else if (type == 's')
                res = ft_strdup(va_arg(*args, char *));
-       else if (**format == 'p')
-               res = ptostr(va_arg(*args, void *));
+       else if (type == 'p')
+               res = ft_itoa_base((intptr_t)va_arg(*args, void *), "0123456789abcdef");
        return (res);
 }
 
-int    handle_conversion(const char **format, va_list *args)
+t_conv parse_format(const char **format, va_list *args)
 {
-       t_flags flags;
-       int             minwidth;
-       int             prec;
-       char    *argstr;
-       int             len;
+       t_conv  conv;
 
-       flags = parse_flags(&format);
-       minwidth = parse_int(&format, &args);
+       conv.flags = parse_flags(format);
+       conv.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);
+               conv.prec = parse_int(format, args);
+       }
+       else
+               conv.prec = -1;
+       conv.type = *((*format)++);
+       return (conv);
+}
+
+typedef struct s_printed
+{
+       char    *left_pad;
+       char    sign;
+       char    *alt;
+       char    *zero_pad;
+       char    *main_part;
+       char    *right_pad;
+}                      t_printed;
+
+char   *create_alt(t_conv conv)
+{
+       if (conv.type == 'p')
+               return (ft_strdup("0x"));
+       else if (conv.flag.alt_mode)
+       {
+               if (conv.type == 'o')
+                       return (ft_strdup("0"));
+               else if (conv.type == 'x')
+                       return (ft_strdup("0x"));
+               else if (conv.type == 'X')
+                       return (ft_strdup("0X"));
+       }
+       return (ft_strdup(""));
+}
+
+void   create_main(char *str, t_conv conv, t_to_print *tp)
+{
+       if  (conv.type == 'd' || conv.type == 'i')
+       {
+               if (*str == '-')
+               {
+                       tp->sign = '-';
+                       tp->main_part = ft_strdup(str + 1);
+               }
+               else
+               {
+                       tp->main_part = ft_strfup(str);
+                       if (conv.flags.sign_show)
+                               tp->sign = '+';
+                       else if (conv.flags.sign_allign)
+                               tp->sign = ' ';
+               }
+       }
+       else if (conv.type == 's' && conv.prec < ft_strlen(str))
+       {
+               tp->main_part = malloc((conv.prec + 1) * sizeof(char));
+               if (tp.main_part == NULL)
+                       return ();
+               ft_strlcpy(tp->main_part, str, conv.prec + 1);
+       }
+       else
+               tp->main_part = ft_strdup(str);
+       return ();
+}
+
+t_printed      formated(char *str, t_conv conv)
+{
+       t_to_print      res;
+
+       init_printed(&res);
+       create_main(str, conv, &res);
+       res.alt = create_alt(conv);
+       
+}
+
+int    handle_conversion(const char **format, va_list *args)
+{
+       t_conv          conv;
+       char            *str;
+       int                     len;
+       t_to_print      to_print;
+
+       ++(*format);
+       conv = parse_format(format, args);
+       temp = base_str_constr(conv.type, args);
+       to_print = formated(temp, conv);
+       free(temp);
+       if (!valid_toprint(to_print))
+               return (-1);
+       ft_putstr_fd(to_print.left_pad, 1);
+       ft_putchar_fd(to_print.sign, 1);
+       ft_putstr_fd(to_print.zero_pad, 1);
+       ft_putstr_fd(to_print.alt, 1);
+       ft_putstr_fd(to_print.main_part, 1);
+       ft_putstr_fd(to_print.right_pad, 1);
        return (len);
 }
 
@@ -193,12 +307,7 @@ int        ft_printf(const char *format, ...)
                if (!*format)
                        break;
                res += handle_conversion(&format, &args);
-               if (err != 0)
-               {
-                       handle_error(err);
-                       break;
-               }
        }
        va_end(args);
-       return ;
+       return (res);
 }