From cef0f5bad06c5380e8e6a0ba61e60b77c7d9d9dc Mon Sep 17 00:00:00 2001 From: Lukas Jiriste Date: Thu, 17 Aug 2023 16:10:35 +0200 Subject: [PATCH] File under construction - first steps. Does not compile nor comply with norminette. --- ft_printf.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 ft_printf.c diff --git a/ft_printf.c b/ft_printf.c new file mode 100644 index 0000000..3b03617 --- /dev/null +++ b/ft_printf.c @@ -0,0 +1,204 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_printf.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/17 09:14:21 by ljiriste #+# #+# */ +/* Updated: 2023/08/17 16:03:10 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include // malloc, free +#include // va_* +#include // 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 // 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 ; +} -- 2.30.2