From: Lukas Jiriste Date: Thu, 24 Aug 2023 07:03:44 +0000 (+0200) Subject: Everything is broken, so I'm committing changes to ft_printf so I don't have to worry... X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=8fdcd7b0789e9a07598d831a202830925f05dc99;p=42%2Fft_printf.git Everything is broken, so I'm committing changes to ft_printf so I don't have to worry about losing changes. (Changed author as I haven't set author and a default was used) --- diff --git a/ft_printf.c b/ft_printf.c index 3b03617..9946fb0 100644 --- a/ft_printf.c +++ b/ft_printf.c @@ -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 + +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 // 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); }