/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* ft_printf.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: narnaud +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/27 08:09:49 by narnaud #+# #+# */ /* Updated: 2023/04/13 12:20:28 by narnaud ### ########.fr */ /* */ /* ************************************************************************** */ #include "ft_printf.h" void get_digit(t_opts *opts, int n) { if (opts->dot) opts->precision = n; else opts->width = n; } const char *handle_options(va_list args, const char *str, t_opts *opts) { if (*str == '-') opts->minus = 1; else if (*str == '0') opts->zero = 1; else if (*str == '#') opts->hash = 1; else if (*str == ' ') opts->space = 1; else if (*str == '+') opts->plus = 1; else if (*str == '.') opts->dot = 1; else if (ft_isdigit(*str)) { get_digit(opts, ft_atoi(str)); while (ft_isdigit(*str) && str++) opts->len++; return (str); } else if (*str == '*') get_digit(opts, va_arg(args, int)); else return (str); opts->len++; return (++str); } void handle_functions(va_list args, const char *str, t_opts *opts) { size_t n; const char *g_types = {"cspdiuxX%"}; static void (*g_printf_fcts[9])(va_list arg, t_opts *opts) = {va_print_char, va_print_str, va_print_ptr, va_print_nbr, va_print_nbr, va_print_unsign, va_print_x, va_print_x_cap, va_print_perc}; n = 0; while (g_types[n] && g_types[n] != *str && ++n) ; if (!g_types[n]) return ; if (opts->minus) opts->zero = 0; if (opts->precision > 0) opts->zero = 0; if (opts->width < 0) { opts->minus = 1; opts->width *= -1; } if (opts->precision < 0) opts->dot = 0; (g_printf_fcts[n])(args, opts); } void ft_format(const char *format, va_list args) { t_opts opts; while (*format) { if (*format == '%' && format++) { opts = (t_opts){0}; while (*format && !ft_strchr("cspdiuxX%", *format)) format = handle_options(args, format, &opts); handle_functions(args, format, &opts); } else add_string(ft_strnew(1, *format), 1); format++; } } int ft_printf(const char *format, ...) { int ret; t_dlist *strings; va_list args; va_start(args, format); ft_format(format, args); ret = 0; strings = get_first(); while (strings) { ret += strings->size; ft_putnstr_fd(strings->size, strings->content, 1); strings = strings->next; } clean_list(); va_end(args); return (ret); } int ft_fprintf(FILE *file, const char *format, ...) { int ret; t_dlist *strings; va_list args; va_start(args, format); ft_format(format, args); ret = 0; strings = get_first(); while (strings) { ret += strings->size; fwrite(strings->content, sizeof(char), strings->size, file); strings = strings->next; } clean_list(); va_end(args); return (ret); } int ft_sprintf(char *str, const char *format, ...) { int ret; t_dlist *strings; va_list args; va_start(args, format); ft_format(format, args); ret = 0; strings = get_first(); while (strings) { ret += strings->size; ft_strlcat(str, strings->content, ret); strings = strings->next; } clean_list(); va_end(args); return (ret); }