From: Lukas Jiriste Date: Tue, 5 Sep 2023 10:30:07 +0000 (+0200) Subject: ft_printf.c was split to files to satisfy max 5 functions per file. X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=307f4821cd651a31fd5538f6cecc14f31d408570;p=42%2Fft_printf.git ft_printf.c was split to files to satisfy max 5 functions per file. ft_printf.h was created for structures and forward declarations to support this split. Makefile was written to build the library. Libft was updated to include potentially useful functions. TESTING IS NEEDED. --- diff --git a/.gitmodules b/.gitmodules index 0d9b2a7..b849a27 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "Libft"] path = Libft - url = git://78.102.58.167/Libft + url = git@78.102.58.167:git_reps/Libft.git diff --git a/Libft b/Libft index 5b3c0fc..2a807f8 160000 --- a/Libft +++ b/Libft @@ -1 +1 @@ -Subproject commit 5b3c0fcbf58c6458fcd10d2ad48c9f698ce7a8c8 +Subproject commit 2a807f82b385f57bca790429e1fa7772b3942cc5 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..dcb449f --- /dev/null +++ b/Makefile @@ -0,0 +1,36 @@ +CC = cc +CFLAGS = -Wall -Wextra -Werror +AR = ar + +RM = rm -f + +INCLUDE = $(addprefix -I, . ./Libft) +SRCDIR = . +# SOURCES = $(addprefix $(SRCDIR)/, ft_putchar.c ft_putstr.c ft_strcmp.c ft_strlen.c ft_swap.c) +SOURCES = $(shell find $(SRCDIR) -maxdepth 1 -name "*.c") +OBJECTS = $(SOURCES:.c=.o) libft.a + +NAME = libftprintf.a + +all : $(NAME) + +$(NAME) : $(OBJECTS) + $(AR) rcs $(NAME) $(OBJECTS) + +libft.a : + $(MAKE) -C ./Libft + cp ./Libft/$@ . + +%.o : %.c + $(CC) $(CFLAGS) -o $@ -c $< $(INCLUDE) + +clean : + $(RM) $(OBJECTS) + $(MAKE) -C ./Libft clean + +fclean : clean + $(RM) $(NAME) + $(MAKE) -C ./Libft fclean + +re : fclean + $(MAKE) all diff --git a/conversion.c b/conversion.c new file mode 100644 index 0000000..c7f722a --- /dev/null +++ b/conversion.c @@ -0,0 +1,81 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* conversion.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/09/05 11:30:56 by ljiriste #+# #+# */ +/* Updated: 2023/09/05 12:10:06 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include // NULL, free +#include //va* +#include "libft.h" +#include "ft_printf.h" + +static char *base_str_constr(char type, va_list *args) +{ + char *res; + + res = NULL; + if (type == 'd' || type == 'i') + res = ft_itoa(va_arg(*args, int)); + 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 (type == 'p') + res = ft_itoa_base((intptr_t)va_arg(*args, void *), "0123456789abcdef"); + return (res); +} + +static int valid_toprint(t_to_print tp) +{ + return (tp.left_pad && tp.zero_pad && tp.main_part && tp.right_pad); +} + +static size_t to_print_len(t_to_print tp) +{ + size_t len; + + len = 0; + len += ft_strlen(tp.left_pad); + len += (tp.sign != '\0'); + len += ft_strlen(tp.alt); + len += ft_strlen(tp.zero_pad); + len += ft_strlen(tp.main_part); + len += ft_strlen(tp.right_pad); + return (len); +} + +int handle_conversion(const char **format, va_list *args) +{ + t_conv conv; + char *temp; + t_to_print to_print; + + ++(*format); + conv = parse_format(format, args); + temp = base_str_constr(conv.type, args); + to_print = formatting(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 (to_print_len(to_print)); +} diff --git a/formatting.c b/formatting.c new file mode 100644 index 0000000..089ea6f --- /dev/null +++ b/formatting.c @@ -0,0 +1,78 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* formatting.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/09/05 11:28:21 by ljiriste #+# #+# */ +/* Updated: 2023/09/05 12:11:32 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include // NULL +#include "libft.h" +#include "ft_printf.h" + +static char *create_alt(t_conv conv) +{ + if (conv.type == 'p') + return (ft_strdup("0x")); + else if (conv.flags.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("")); +} + +static 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_strdup(str); + if (conv.flags.sign_show) + tp->sign = '+'; + else if (conv.flags.sign_allign) + tp->sign = ' '; + } + } + else if (conv.type == 's' + && (size_t)conv.prec < ft_strlen(str) && conv.prec >= 0) + tp->main_part = ft_strndup(str, conv.prec); + else + tp->main_part = ft_strdup(str); + return ; +} + +static void init_printed(t_to_print *tp) +{ + tp->left_pad = NULL; + tp->sign = '\0'; + tp->zero_pad = NULL; + tp->main_part = NULL; + tp->right_pad = NULL; + return ; +} + +t_to_print formatting(char *str, t_conv conv) +{ + t_to_print res; + + init_printed(&res); + create_main(str, conv, &res); + res.alt = create_alt(conv); + create_padding(&res, conv); + return (res); +} diff --git a/ft_printf.c b/ft_printf.c index ef106de..db1fbce 100644 --- a/ft_printf.c +++ b/ft_printf.c @@ -6,14 +6,14 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/08/17 09:14:21 by ljiriste #+# #+# */ -/* Updated: 2023/08/17 16:03:10 by ljiriste ### ########.fr */ +/* Updated: 2023/09/05 12:10:57 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ -#include // malloc, free -#include // va_* +#include // va_* #include // write #include "libft.h" +#include "ft_printf.h" int print_ordinary(const char **s) { @@ -27,370 +27,6 @@ int print_ordinary(const char **s) return (len); } -typedef struct s_flags -{ - int alt_mode; - int zero_pad; - int left_adjust; - int sign_allign; - 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.alt_mode = 0; - flags.zero_pad = 0; - flags.left_adjust = 0; - flags.sign_allign = 0; - flags.sign_show = 0; - while (1) - { - 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); -} - -#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); -} - -intptr_t ft_abs(intptr_t n) -{ - if (n < 0) - return (-n); - else - return (n); -} - -char *ft_itoa_base(intptr_t n, const char *base) -{ - int size; - int base_len; - char *res; - - if (!valid_base(base)) - return (NULL); - base_len = ft_strlen(base); - size = size_needed(n, base_len); - res = malloc(size); - if (res == NULL) - return (res); - if (n < 0) - res[0] = '-'; - res[size--] = '\0'; - while (n != 0) - { - res[size--] = base[ft_abs(n % base_len)]; - n /= base_len; - } - return (res); -} - -char *ft_ctoa(char c) -{ - char *res; - - res = malloc(2 * sizeof(char)); - if (res == NULL) - return (res); - res[0] = c; - res[1] = '\0'; - return (res); -} - -char *base_str_constr(char type, va_list *args) -{ - char *res; - - res = NULL; - if (type == 'd' || type == 'i') - res = ft_itoa(va_arg(*args, int)); - 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 (type == 'p') - res = ft_itoa_base((intptr_t)va_arg(*args, void *), "0123456789abcdef"); - return (res); -} - -t_conv parse_format(const char **format, va_list *args) -{ - t_conv conv; - - conv.flags = parse_flags(format); - conv.minwidth = parse_int(format, args); - if (**format == '.') - { - ++(*format); - conv.prec = parse_int(format, args); - } - else - conv.prec = -1; - conv.type = *((*format)++); - return (conv); -} - -typedef struct s_to_print -{ - char *left_pad; - char sign; - char *alt; - char *zero_pad; - char *main_part; - char *right_pad; -} t_to_print; - -char *create_alt(t_conv conv) -{ - if (conv.type == 'p') - return (ft_strdup("0x")); - else if (conv.flags.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_strdup(str); - if (conv.flags.sign_show) - tp->sign = '+'; - else if (conv.flags.sign_allign) - tp->sign = ' '; - } - } - else if (conv.type == 's' - && (size_t)conv.prec < ft_strlen(str) && conv.prec >= 0) - tp->main_part = ft_strndup(str, conv.prec); - else - tp->main_part = ft_strdup(str); - return ; -} - -void init_printed(t_to_print *tp) -{ - tp->left_pad = NULL; - tp->sign = '\0'; - tp->zero_pad = NULL; - tp->main_part = NULL; - tp->right_pad = NULL; - return ; -} - -char *rep_char(char c, int n) -{ - char *res; - - if (n < 0) - n = 0; - res = malloc(++n); - if (res == NULL) - return (res); - res[--n] = '\0'; - while (n > 0) - res[--n] = c; - return (res); -} - -void lengthen_by_zeros(char **str, int n) -{ - char *temp; - size_t size; - - if (n <= 0) - return ; - temp = *str; - size = ft_strlen(temp) + n + 1; - *str = malloc(size); - if (*str == NULL) - { - free(temp); - return ; - } - ft_strlcpy(*str, temp, size); - free(temp); - while (n > 0) - (*str)[size - (n--) - 1] = '0'; - (*str)[size - 1] = '\0'; - return ; -} - -void create_padding(t_to_print *tp, t_conv conv) -{ - size_t len; - - len = ft_strlen(tp->main_part); - tp->zero_pad = rep_char('0', conv.prec - len); - len += ft_strlen(tp->zero_pad) + ft_strlen(tp->alt) + (tp->sign != '\0'); - if (conv.flags.left_adjust) - { - tp->right_pad = rep_char(' ', conv.minwidth - len); - tp->left_pad = ft_strdup(""); - } - else - { - tp->right_pad = ft_strdup(""); - if (!conv.flags.zero_pad || conv.type == 's') - tp->left_pad = rep_char(' ', conv.minwidth - len); - else if (conv.flags.zero_pad) - { - tp->left_pad = ft_strdup(""); - lengthen_by_zeros(&(tp->zero_pad), conv.minwidth - len); - } - } - return ; -} - -t_to_print formated(char *str, t_conv conv) -{ - t_to_print res; - - init_printed(&res); - create_main(str, conv, &res); - res.alt = create_alt(conv); - create_padding(&res, conv); - return (res); -} - -int valid_toprint(t_to_print tp) -{ - return (tp.left_pad && tp.zero_pad && tp.main_part && tp.right_pad); -} - -size_t to_print_len(t_to_print tp) -{ - size_t len; - - len = 0; - len += ft_strlen(tp.left_pad); - len += (tp.sign != '\0'); - len += ft_strlen(tp.alt); - len += ft_strlen(tp.zero_pad); - len += ft_strlen(tp.main_part); - len += ft_strlen(tp.right_pad); - return (len); -} - -int handle_conversion(const char **format, va_list *args) -{ - t_conv conv; - char *temp; - 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 (to_print_len(to_print)); -} - int ft_printf(const char *format, ...) { va_list args; diff --git a/ft_printf.h b/ft_printf.h new file mode 100644 index 0000000..931ae1a --- /dev/null +++ b/ft_printf.h @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_printf.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/09/05 12:00:16 by ljiriste #+# #+# */ +/* Updated: 2023/09/05 12:27:18 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_PRINTF_H +# define FT_PRINTF_H + +# include + +typedef struct s_flags +{ + int alt_mode; + int zero_pad; + int left_adjust; + int sign_allign; + int sign_show; +} t_flags; + +typedef struct s_conv +{ + t_flags flags; + int minwidth; + int prec; + char type; +} t_conv; + +typedef struct s_to_print +{ + char *left_pad; + char sign; + char *alt; + char *zero_pad; + char *main_part; + char *right_pad; +} t_to_print; + +int ft_printf(const char *format, ...); +int handle_conversion(const char **format, va_list *args); +t_to_print formatting(char *str, t_conv conv); +t_conv parse_format(const char **format, va_list *args); +void create_padding(t_to_print *tp, t_conv conv); + +#endif diff --git a/padding.c b/padding.c new file mode 100644 index 0000000..600d5cf --- /dev/null +++ b/padding.c @@ -0,0 +1,79 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* padding.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/09/05 11:25:46 by ljiriste #+# #+# */ +/* Updated: 2023/09/05 12:13:14 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include //malloc +#include "libft.h" +#include "ft_printf.h" + +static char *repeat_char(char c, int n) +{ + char *res; + + if (n < 0) + n = 0; + res = malloc(++n); + if (res == NULL) + return (res); + res[--n] = '\0'; + while (n > 0) + res[--n] = c; + return (res); +} + +static void lengthen_by_zeros(char **str, int n) +{ + char *temp; + size_t size; + + if (n <= 0) + return ; + temp = *str; + size = ft_strlen(temp) + n + 1; + *str = malloc(size); + if (*str == NULL) + { + free(temp); + return ; + } + ft_strlcpy(*str, temp, size); + free(temp); + while (n > 0) + (*str)[size - (n--) - 1] = '0'; + (*str)[size - 1] = '\0'; + return ; +} + +void create_padding(t_to_print *tp, t_conv conv) +{ + size_t len; + + len = ft_strlen(tp->main_part); + tp->zero_pad = repeat_char('0', conv.prec - len); + len += ft_strlen(tp->zero_pad) + ft_strlen(tp->alt) + (tp->sign != '\0'); + if (conv.flags.left_adjust) + { + tp->right_pad = repeat_char(' ', conv.minwidth - len); + tp->left_pad = ft_strdup(""); + } + else + { + tp->right_pad = ft_strdup(""); + if (!conv.flags.zero_pad || conv.type == 's') + tp->left_pad = repeat_char(' ', conv.minwidth - len); + else if (conv.flags.zero_pad) + { + tp->left_pad = ft_strdup(""); + lengthen_by_zeros(&(tp->zero_pad), conv.minwidth - len); + } + } + return ; +} diff --git a/parsing.c b/parsing.c new file mode 100644 index 0000000..4058ed4 --- /dev/null +++ b/parsing.c @@ -0,0 +1,78 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parsing.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/09/05 10:50:54 by ljiriste #+# #+# */ +/* Updated: 2023/09/05 12:12:41 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include // va_* +#include "libft.h" +#include "ft_printf.h" + +static 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 (1) + { + 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); + } +} + +static 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); +} + +t_conv parse_format(const char **format, va_list *args) +{ + t_conv conv; + + conv.flags = parse_flags(format); + conv.minwidth = parse_int(format, args); + if (**format == '.') + { + ++(*format); + conv.prec = parse_int(format, args); + } + else + conv.prec = -1; + conv.type = *((*format)++); + return (conv); +}