return (len);
}
-typedef struct s_flags
+typedef struct s_flags
{
int alt_mode;
int zero_pad;
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;
flags.left_adjust = 0;
flags.sign_allign = 0;
flags.sign_show = 0;
- while (true)
+ while (1)
{
if (**format == '#')
flags.alt_mode = 1;
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);
}
if (!*format)
break;
res += handle_conversion(&format, &args);
- if (err != 0)
- {
- handle_error(err);
- break;
- }
}
va_end(args);
- return ;
+ return (res);
}