diff --git a/Makefile b/Makefile index a9a8b0a..0db9a66 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ NAME = libftprintf.a -SRCS = ft_printf.c ft_putchars.c ft_putnbrs.c ft_putptr.c ft_putx.c utils.c opts.c +SRCS = ft_print_chars.c ft_print_hexs.c ft_print_nbrs.c ft_print_opts.c ft_print_ptrs.c ft_printf.c OBJS = ${SRCS:.c=.o} RM = rm -rf diff --git a/ft_putchars.c b/ft_print_chars.c similarity index 73% rename from ft_putchars.c rename to ft_print_chars.c index a132153..3b820fb 100644 --- a/ft_putchars.c +++ b/ft_print_chars.c @@ -15,42 +15,42 @@ int ft_print_char(int ch, t_opts *opts) { char c; - int ret; + int ret; c = (char)ch; - ret = 1; - if (opts->minus) - { - ft_putchar_fd(c, 1); - while (opts->width-- > 1 && ++ret) - ft_putchar_fd(' ', 1); - } - else - { - while (opts->width-- > 1 && ++ret) - ft_putchar_fd(' ', 1); - ft_putchar_fd(c, 1); - } - return (ret); + ret = 1; + if (opts->minus) + { + ft_putchar_fd(c, 1); + while (opts->width-- > 1 && ++ret) + ft_putchar_fd(' ', 1); + } + else + { + while (opts->width-- > 1 && ++ret) + ft_putchar_fd(' ', 1); + ft_putchar_fd(c, 1); + } + return (ret); } int ft_print_str(char *str, t_opts *opts) { - int i; - char *formated; + int i; + char *formated; i = 0; - if (!str) - { - if (!opts->dot || opts->precision >= 6) - str = "(null)"; - else - str = ""; - } - formated = str_opts_transform(str, opts); + if (!str) + { + if (!opts->dot || opts->precision >= 6) + str = "(null)"; + else + str = ""; + } + formated = str_opts_transform(str, opts); while (formated[i]) ft_putchar_fd(formated[i++], 1); - free(formated); + free(formated); return (i); } diff --git a/ft_putx.c b/ft_print_hexs.c similarity index 70% rename from ft_putx.c rename to ft_print_hexs.c index 381137b..65ea57e 100644 --- a/ft_putx.c +++ b/ft_print_hexs.c @@ -1,7 +1,7 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* ft_print_x.c :+: :+: :+: */ +/* ft_print_x.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: narnaud +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ @@ -15,44 +15,44 @@ int ft_print_x(unsigned int n, t_opts *opts) { char *raw; - char *nbr; - char *tmp; + char *nbr; + char *tmp; int ret; - raw = ft_itox((unsigned long int)n, "0123456789abcdef"); - if (opts->hash && n != 0) - { - tmp = raw; - raw = ft_strjoin("0x", raw); - free(tmp); - } - nbr = uint_opts_transform(n, raw, opts); - opts->dot = 0; + raw = ft_itox((unsigned long int)n, "0123456789abcdef"); + if (opts->hash && n != 0) + { + tmp = raw; + raw = ft_strjoin("0x", raw); + free(tmp); + } + nbr = uint_opts_transform(n, raw, opts); + opts->dot = 0; ret = ft_print_str(nbr, opts); free(raw); - free(nbr); + free(nbr); return (ret); } int ft_print_x_cap(unsigned int n, t_opts *opts) { char *raw; - char *tmp; - char *nbr; + char *tmp; + char *nbr; int ret; raw = ft_itox((unsigned long int)n, "0123456789ABCDEF"); - if (opts->hash && n != 0) - { - tmp = raw; - raw = ft_strjoin("0X", raw); - free(tmp); - } - nbr = uint_opts_transform(n, raw, opts); - opts->dot = 0; + if (opts->hash && n != 0) + { + tmp = raw; + raw = ft_strjoin("0X", raw); + free(tmp); + } + nbr = uint_opts_transform(n, raw, opts); + opts->dot = 0; ret = ft_print_str(nbr, opts); free(raw); - free(nbr); + free(nbr); return (ret); } diff --git a/ft_putnbrs.c b/ft_print_nbrs.c similarity index 80% rename from ft_putnbrs.c rename to ft_print_nbrs.c index 30c06fd..a7d1f9b 100644 --- a/ft_putnbrs.c +++ b/ft_print_nbrs.c @@ -1,7 +1,7 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* ft_print_nbrs.c :+: :+: :+: */ +/* ft_print_nbrs.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: narnaud +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ @@ -15,31 +15,31 @@ int ft_print_nbr(int n, const char *str, t_opts *opts) { char *nbr; - char *raw; + char *raw; int ret; (void)*str; raw = ft_itoa(n); - nbr = int_opts_transform(n, raw, opts); - opts->dot = 0; - ret = ft_print_str(nbr, opts); - free(raw); + nbr = int_opts_transform(n, raw, opts); + opts->dot = 0; + ret = ft_print_str(nbr, opts); + free(raw); free(nbr); return (ret); } int ft_print_unsign(unsigned int n, const char *str, t_opts *opts) { - char *raw; + char *raw; char *nbr; int ret; (void)*str; - raw = ft_utoa(n); - nbr = uint_opts_transform(n, raw, opts); - opts->dot = 0; + raw = ft_utoa(n); + nbr = uint_opts_transform(n, raw, opts); + opts->dot = 0; ret = ft_print_str(nbr, opts); - free(raw); + free(raw); free(nbr); return (ret); } diff --git a/ft_print_opts.c b/ft_print_opts.c new file mode 100644 index 0000000..2166ddc --- /dev/null +++ b/ft_print_opts.c @@ -0,0 +1,108 @@ +#include "ft_printf.h" + +char *zero_fill(char *nbr, t_opts *opts) +{ + int len; + char *fill; + + fill = NULL; + if (opts->zero) + len = opts->width - ft_strlen(nbr); + else if (opts->dot) + len = opts->precision - ft_strlen(nbr); + else + return (NULL); + if (len < 0 || (opts->zero && len == 0)) + return (NULL); + if ((nbr[0] == '-' || nbr[0] == '+' || nbr[0] == ' ') && opts->dot) + fill = ft_strnew(len + 1, '0'); + else + fill = ft_strnew(len, '0'); + if (nbr[0] == '-' || nbr[0] == '+' || nbr[0] == ' ') + { + fill[0] = nbr[0]; + nbr[0] = '0'; + } + return (fill); +} + +char *int_opts_transform(int n, char *nbr, t_opts *opts) +{ + if (opts->plus && n >= 0) + nbr = ft_strjoin("+", nbr); + else if (opts->space && n >= 0) + nbr = ft_strjoin(" ", nbr); + else if (opts->precision == 0 && opts->dot && n == 0 + && opts->len) + nbr = ft_strdup(""); + else + nbr = ft_strdup(nbr); + if (opts->precision > 0) + nbr = ft_append(zero_fill(nbr, opts), nbr); + else if (opts->zero && !opts->dot) + nbr = ft_append(zero_fill(nbr, opts), nbr); + return (nbr); +} + +char *uint_opts_transform(unsigned int n, char *nbr, t_opts *opts) +{ + if (opts->plus) + nbr = ft_strjoin("+", nbr); + else if (opts->space) + nbr = ft_strjoin(" ", nbr); + else if (opts->precision == 0 && opts->dot && n == 0 + && opts->len) + nbr = ft_strdup(""); + else + nbr = ft_strdup(nbr); + if (opts->precision > 0) + nbr = ft_append(zero_fill(nbr, opts), nbr); + else if (opts->zero && !opts->dot) + nbr = ft_append(zero_fill(nbr, opts), nbr); + return (nbr); +} + +char *ptr_opts_transform(char *nbr, t_opts *opts) +{ + if (opts->plus) + nbr = ft_strjoin("+", nbr); + else if (opts->space) + nbr = ft_strjoin(" ", nbr); + else if (opts->precision == 0 && opts->dot + && opts->len) + nbr = ft_strdup(""); + else + nbr = ft_strdup(nbr); + if (opts->precision > 0) + nbr = ft_append(zero_fill(nbr, opts), nbr); + else if (opts->zero && !opts->dot) + nbr = ft_append(zero_fill(nbr, opts), nbr); + return (nbr); +} + +char *str_opts_transform(char *str, t_opts *opts) +{ + int len; + char *tmp; + char *sub; + + tmp = NULL; + sub = NULL; + if (opts->dot) + sub = ft_substr(str, 0, opts->precision); + if (sub) + str = sub; + len = opts->width - (int)ft_strlen(str); + tmp = ft_strnew(len, ' '); + if (!opts->minus && len > 0) + str = ft_strjoin(tmp, str); + else if (opts->minus && len > 0) + str = ft_strjoin(str, tmp); + else + str = ft_strdup(str); + if (tmp) + free(tmp); + if (sub) + free(sub); + return (str); +} diff --git a/ft_putptr.c b/ft_print_ptrs.c similarity index 73% rename from ft_putptr.c rename to ft_print_ptrs.c index 65d9eea..b05e474 100644 --- a/ft_putptr.c +++ b/ft_print_ptrs.c @@ -1,7 +1,7 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* ft_print_ptr.c :+: :+: :+: */ +/* ft_print_ptr.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: narnaud +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ @@ -15,21 +15,21 @@ int ft_print_ptr(void *ptr, t_opts *opts) { char *raw; - char *nbr; + char *nbr; int ret; - if (ptr == NULL) - raw = ft_strdup("(nil)"); - else - { - raw = ft_itox((unsigned long long int)ptr, "0123456789abcdef"); - raw = ft_append(ft_strdup("0x"), raw); - } - nbr = ptr_opts_transform(raw, opts); - opts->dot = 0; + if (ptr == NULL) + raw = ft_strdup("(nil)"); + else + { + raw = ft_itox((unsigned long long int)ptr, "0123456789abcdef"); + raw = ft_append(ft_strdup("0x"), raw); + } + nbr = ptr_opts_transform(raw, opts); + opts->dot = 0; ret = ft_print_str(nbr, opts); - free(raw); - free(nbr); + free(raw); + free(nbr); return (ret); } diff --git a/ft_printf.c b/ft_printf.c index 7c0ad08..69e8eae 100644 --- a/ft_printf.c +++ b/ft_printf.c @@ -12,85 +12,92 @@ #include "ft_printf.h" -#include "./libft/libft.h" +void get_digit(t_opts *opts, int n) +{ + if (opts->dot) + opts->precision = n; + else + opts->width = n; +} -int handle_options(va_list args, const char *str, t_opts *opts) +const char *handle_options(va_list args, const char *str, t_opts *opts) { - while (*str && !ft_strchr("cspdiuxX%", *str)) { - 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)) - { - if (opts->dot) opts->precision = ft_atoi(str); - else opts->width = ft_atoi(str); - while (ft_isdigit(*str)) { - str++; - opts->len++; - } - continue; - } else if (*str == '*') - { - if (opts->dot) opts->precision = va_arg(args, int); - else opts->width = va_arg(args, int); - } else return (0); - str++; - opts->len++; - } - return (1); + 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); } -int handle_functions(va_list args, const char *str, t_opts *opts) +int handle_functions(va_list args, const char *str, t_opts *opts) { - size_t n = 0; - size_t ret = 0; - const char *g_types = {"cspdiuxX%"}; - static int (*g_printf_fcts[9])(va_list arg, const char *str, 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}; - while (g_types[n] && g_types[n] != *str) - n++; - if (g_types[n]) { - 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; - ret += (g_printf_fcts[n])(args, str, opts); - } - return ret; + size_t n; + const char *g_types = {"cspdiuxX%"}; + static int (*g_printf_fcts[9])(va_list arg, const char *str, + 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 (0); + 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; + return ((g_printf_fcts[n])(args, str, opts)); } -int ft_printf(const char *str, ...) +int ft_printf(const char *str, ...) { - va_list args; - size_t i; - t_opts opts; + va_list args; + size_t i; + t_opts opts; - i = 0; - va_start(args, str); - while (*str) - { - if (*str == '%' && str++) - { - opts = (t_opts){0}; - if (handle_options(args, str, &opts)) - { - str += opts.len; - i += handle_functions(args, str, &opts); - } - } - else if (++i) - ft_putchar_fd(*str, 1); - str++; - } - va_end(args); - return (i); + i = 0; + va_start(args, str); + while (*str) + { + if (*str == '%' && str++) + { + opts = (t_opts){0}; + while (*str && !ft_strchr("cspdiuxX%", *str)) + str = handle_options(args, str, &opts); + i += handle_functions(args, str, &opts); + } + else if (++i) + ft_putchar_fd(*str, 1); + str++; + } + va_end(args); + return (i); } diff --git a/ft_printf.h b/ft_printf.h index c32a226..04a54f4 100644 --- a/ft_printf.h +++ b/ft_printf.h @@ -10,8 +10,7 @@ /* */ /* ************************************************************************** */ -#ifndef FT_PRINTF_H -# define FT_PRINTF_H +#pragma once # define MEM_ADD_SIZE 6 @@ -23,23 +22,18 @@ typedef struct s_opts { int len; int width; int precision; - int zero; - int minus; - int dot; - int hash; - int space; - int plus; + int zero : 1; + int minus : 1; + int dot : 1; + int hash : 1; + int space : 1; + int plus : 1; } t_opts; char *int_opts_transform(int n, char *nbr, t_opts *opts); char *uint_opts_transform(unsigned int n, char *nbr, t_opts *opts); char *ptr_opts_transform(char *ptr, t_opts *opts); char *str_opts_transform(char *str, t_opts *opts); -char *ft_append(char *s1, char *s2); -char *ft_zero_fill(char *nbr, char c, t_opts *opts); -char *ft_strnew(int n, char c); - -int ft_putnstr(char *str, int n); int ft_print_char(int ch, t_opts *opts); int ft_print_str(char *str, t_opts *opts); @@ -52,5 +46,3 @@ int va_print_x(va_list va_uint, const char *str, t_opts *opts); int va_print_x_cap(va_list va_uint, const char *str, t_opts *opts); int va_print_perc(va_list va, const char *str, t_opts *opts); int ft_printf(const char *str, ...); - -#endif diff --git a/libft b/libft index 840a269..9154239 160000 --- a/libft +++ b/libft @@ -1 +1 @@ -Subproject commit 840a26935181c35cd8416853f1aad9a0bf99621f +Subproject commit 91542393af2673f7cba570fc4b868294810f1abc diff --git a/main.c b/main.c deleted file mode 100644 index ce0e077..0000000 --- a/main.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "ft_printf.h" - - -int main(void) -{ - ft_printf("%.4s\n", "Hello world!\n"); - return 0; -} diff --git a/opts.c b/opts.c deleted file mode 100644 index 432cbf7..0000000 --- a/opts.c +++ /dev/null @@ -1,87 +0,0 @@ -#include "ft_printf.h" - -char *int_opts_transform(int n, char *nbr, t_opts *opts) -{ - if (opts->plus && n>=0) - nbr = ft_strjoin("+", nbr); - else if (opts->space && n>=0) - nbr = ft_strjoin(" ", nbr); - else if (opts->precision == 0 && opts->dot && n == 0 && - opts->len) - nbr = ft_strdup(""); - else - nbr = ft_strdup(nbr); - - if (opts->precision > 0) - nbr = ft_append(ft_zero_fill(nbr, '0', opts), nbr); - else if (opts->zero && !opts->dot) - nbr = ft_append(ft_zero_fill(nbr, '0', opts), nbr); - - return (nbr); -} - -char *uint_opts_transform(unsigned int n, char *nbr, t_opts *opts) -{ - if (opts->plus) - nbr = ft_strjoin("+", nbr); - else if (opts->space) - nbr = ft_strjoin(" ", nbr); - else if (opts->precision == 0 && opts->dot && n == 0 && - opts->len) - nbr = ft_strdup(""); - else - nbr = ft_strdup(nbr); - - if (opts->precision > 0) - nbr = ft_append(ft_zero_fill(nbr, '0', opts), nbr); - else if (opts->zero && !opts->dot) - nbr = ft_append(ft_zero_fill(nbr, '0', opts), nbr); - - return (nbr); -} - -char *ptr_opts_transform(char *nbr, t_opts *opts) -{ - if (opts->plus) - nbr = ft_strjoin("+", nbr); - else if (opts->space) - nbr = ft_strjoin(" ", nbr); - else if (opts->precision == 0 && opts->dot && - opts->len) - nbr = ft_strdup(""); - else - nbr = ft_strdup(nbr); - - if (opts->precision > 0) - nbr = ft_append(ft_zero_fill(nbr, '0', opts), nbr); - else if (opts->zero && !opts->dot) - nbr = ft_append(ft_zero_fill(nbr, '0', opts), nbr); - - return (nbr); -} - -char *str_opts_transform(char *str, t_opts *opts) -{ - int len; - char *tmp = NULL; - char *sub = NULL; - - if (opts->dot) - sub = ft_substr(str, 0, opts->precision); - if (sub) - str = sub; - len = opts->width - (int)ft_strlen(str); - tmp = ft_strnew(len, ' '); - if (!opts->minus && len > 0) - str = ft_strjoin(tmp, str); - else if (opts->minus && len > 0) - str = ft_strjoin(str, tmp); - else - str = ft_strdup(str); - if (tmp) - free(tmp); - if (sub) - free(sub); - - return (str); -} diff --git a/utils.c b/utils.c deleted file mode 100644 index 8c8d0a3..0000000 --- a/utils.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "ft_printf.h" - -char *ft_strnew(int n, char c) -{ - char *str = NULL; - - if (n < 0) - return (NULL); - str = malloc(n + 1); - if (!str) - return (NULL); - str[n] = '\0'; - while (--n >= 0) - str[n] = c; - return (str); -} - -char *ft_zero_fill(char *nbr, char c, t_opts *opts) -{ - int len; - char *fill = NULL; - - if (opts->zero) - len = opts->width - ft_strlen(nbr); - else if (opts->dot) - len = opts->precision - ft_strlen(nbr); - else - return (NULL); - - if (len < 0 || (opts->zero && len == 0)) - return (NULL); - - if ((nbr[0] == '-' || nbr[0] == '+' || nbr[0] == ' ') && opts->dot) - fill = ft_strnew(len + 1, c); - else - fill = ft_strnew(len , c); - - if (nbr[0] == '-' || nbr[0] == '+' || nbr[0] == ' ') - { - fill[0] = nbr[0]; - nbr[0] = '0'; - } - - return (fill); -} - -char *ft_append(char *s1, char *s2) { - char *ret = NULL; - if (!s1) - return (s2); - if (!s2) - return (s1); - ret = ft_strjoin(s1, s2); - free(s1); - free(s2); - return (ret); -}