[submodule "Libft"]
path = Libft
- url = git://78.102.58.167/Libft
+ url = git@78.102.58.167:git_reps/Libft.git
-Subproject commit 5b3c0fcbf58c6458fcd10d2ad48c9f698ce7a8c8
+Subproject commit 2a807f82b385f57bca790429e1fa7772b3942cc5
--- /dev/null
+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
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* conversion.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2023/09/05 11:30:56 by ljiriste #+# #+# */
+/* Updated: 2023/09/05 12:10:06 by ljiriste ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include <stdlib.h> // NULL, free
+#include <stdarg.h> //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));
+}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* formatting.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2023/09/05 11:28:21 by ljiriste #+# #+# */
+/* Updated: 2023/09/05 12:11:32 by ljiriste ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include <stddef.h> // 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);
+}
/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <stdlib.h> // malloc, free
-#include <stdarg.h> // va_*
+#include <stdarg.h> // va_*
#include <unistd.h> // write
#include "libft.h"
+#include "ft_printf.h"
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 <stdint.h>
-
-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;
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ft_printf.h :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* 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 <stdarg.h>
+
+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
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* padding.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2023/09/05 11:25:46 by ljiriste #+# #+# */
+/* Updated: 2023/09/05 12:13:14 by ljiriste ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include <stdlib.h> //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 ;
+}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* parsing.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2023/09/05 10:50:54 by ljiriste #+# #+# */
+/* Updated: 2023/09/05 12:12:41 by ljiriste ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include <stdarg.h> // 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);
+}