From 55767c36c6280831e6a0b68f27777df3362468b0 Mon Sep 17 00:00:00 2001 From: Tanguy MAZE Date: Thu, 7 Mar 2019 19:06:02 +0100 Subject: [PATCH] plop added ft_getline WIP --- Makefile | 11 ++- ft_getline.c | 76 +++++++++++++++ ft_printf.c | 91 ++++++++++++++++++ ft_printf_check_fields.c | 142 ++++++++++++++++++++++++++++ ft_printf_check_type.c | 69 ++++++++++++++ ft_printf_tools.c | 49 ++++++++++ ft_printf_tools_char.c | 30 ++++++ ft_printf_tools_float.c | 122 ++++++++++++++++++++++++ ft_printf_tools_hexa.c | 120 +++++++++++++++++++++++ ft_printf_tools_int.c | 113 ++++++++++++++++++++++ ft_printf_tools_lenght.c | 50 ++++++++++ ft_printf_tools_malloc_size.c | 79 ++++++++++++++++ ft_printf_tools_oct.c | 110 ++++++++++++++++++++++ ft_printf_tools_prec_size.c | 97 +++++++++++++++++++ ft_printf_tools_str.c | 64 +++++++++++++ ft_printf_tools_unsigned_int.c | 99 +++++++++++++++++++ ft_printf_tools_wchar_t.c | 113 ++++++++++++++++++++++ ft_printf_tools_wstr.c | 89 ++++++++++++++++++ ft_strjoin.c | 2 +- libft.h | 167 ++++++++++++++++++++++++++++++++- 20 files changed, 1686 insertions(+), 7 deletions(-) create mode 100644 ft_getline.c create mode 100644 ft_printf.c create mode 100644 ft_printf_check_fields.c create mode 100644 ft_printf_check_type.c create mode 100644 ft_printf_tools.c create mode 100644 ft_printf_tools_char.c create mode 100644 ft_printf_tools_float.c create mode 100644 ft_printf_tools_hexa.c create mode 100644 ft_printf_tools_int.c create mode 100644 ft_printf_tools_lenght.c create mode 100644 ft_printf_tools_malloc_size.c create mode 100644 ft_printf_tools_oct.c create mode 100644 ft_printf_tools_prec_size.c create mode 100644 ft_printf_tools_str.c create mode 100644 ft_printf_tools_unsigned_int.c create mode 100644 ft_printf_tools_wchar_t.c create mode 100644 ft_printf_tools_wstr.c diff --git a/Makefile b/Makefile index 2893bd0..282b31c 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # By: tmaze +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2018/04/07 12:47:06 by tmaze #+# #+# # -# Updated: 2019/02/28 14:33:03 by tmaze ### ########.fr # +# Updated: 2019/03/07 16:19:33 by tmaze ### ########.fr # # # #******************************************************************************# @@ -19,7 +19,7 @@ NAME = libft.a SRCS = ft_memset.c ft_bzero.c ft_memcpy.c ft_memccpy.c ft_memmove.c ft_memchr.c ft_memcmp.c ft_strlen.c ft_strdup.c ft_strcpy.c ft_strncpy.c ft_strcat.c ft_strncat.c ft_strlcat.c ft_strchr.c ft_strrchr.c ft_strstr.c ft_strnstr.c ft_strcmp.c ft_strncmp.c ft_atoi.c ft_isalpha.c ft_isdigit.c ft_isalnum.c ft_isascii.c ft_isprint.c ft_toupper.c ft_tolower.c \ ft_memalloc.c ft_memdel.c ft_strnew.c ft_strdel.c ft_strclr.c ft_striter.c ft_striteri.c ft_strmap.c ft_strmapi.c ft_strequ.c ft_strnequ.c ft_strsub.c ft_strjoin.c ft_strtrim.c ft_strsplit.c ft_itoa.c ft_putchar.c ft_putstr.c ft_putendl.c ft_putnbr.c ft_putchar_fd.c ft_putstr_fd.c ft_putendl_fd.c ft_putnbr_fd.c\ ft_lstnew.c ft_lstdelone.c ft_lstdel.c ft_lstadd.c ft_lstiter.c ft_lstmap.c \ -ft_isupper.c ft_islower.c ft_str_is_alpha.c ft_str_is_lowercase.c ft_str_is_numeric.c ft_str_is_printable.c ft_str_is_uppercase.c ft_strcapitalize.c ft_strlcpy.c ft_strlowcase.c ft_strupcase.c ft_lstsize.c ft_lstgetat.c ft_lstgetlast.c ft_sort_params.c ft_print_words_tables.c ft_lstaddend.c ft_strndup.c ft_abs.c ft_strnchr.c ft_strrnchr.c get_next_line.c ft_del_words_tables.c ft_putstrn.c ft_nbrlen.c ft_putstrpad.c ft_putnbrpad.c ft_lstsort.c ft_lstaddsort.c ft_round.c ft_realpath.c ft_iswhitespace.c ft_issign.c ft_hasdigit.c ft_strsplitwhitespace.c ft_atois.c +ft_isupper.c ft_islower.c ft_str_is_alpha.c ft_str_is_lowercase.c ft_str_is_numeric.c ft_str_is_printable.c ft_str_is_uppercase.c ft_strcapitalize.c ft_strlcpy.c ft_strlowcase.c ft_strupcase.c ft_lstsize.c ft_lstgetat.c ft_lstgetlast.c ft_sort_params.c ft_print_words_tables.c ft_lstaddend.c ft_strndup.c ft_abs.c ft_strnchr.c ft_strrnchr.c get_next_line.c ft_del_words_tables.c ft_putstrn.c ft_nbrlen.c ft_putstrpad.c ft_putnbrpad.c ft_lstsort.c ft_lstaddsort.c ft_round.c ft_realpath.c ft_iswhitespace.c ft_issign.c ft_hasdigit.c ft_strsplitwhitespace.c ft_atois.c ft_getline.c OBJDIR = objs OBJS = $(SRCS:.c=.o) @@ -30,19 +30,20 @@ INCLS = -I. all: $(NAME) -$(NAME): $(OBJP) +$(NAME): $(OBJDIR) $(OBJP) ar rcs $(NAME) $(OBJP) $(OBJDIR): mkdir $@ -$(OBJDIR)/%.o: %.c $(OBJDIR) libft.h +$(OBJDIR)/%.o: %.c libft.h $(CC) $(CCFLAGS) $(CCSTD) $(INCLS) -c $< -o $@ clean: - rm -f $(OBJS) + rm -f $(OBJP) fclean: clean rm -f $(NAME) + rm -rf $(OBJDIR) re: fclean all diff --git a/ft_getline.c b/ft_getline.c new file mode 100644 index 0000000..a1ca7d9 --- /dev/null +++ b/ft_getline.c @@ -0,0 +1,76 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_getline.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tmaze +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/03/07 15:12:59 by tmaze #+# #+# */ +/* Updated: 2019/03/07 19:02:51 by tmaze ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static char *supercat(char **s1, char *s2[BUFF_SIZE + 1]) +{ + char *tmp; + + printf("lengths supercat %zu\n", ft_strlen(*s2)); + if ((tmp = ft_strjoin(*s1, *s2)) == NULL) + return (NULL); + ft_strdel(s1); + ft_strclr(*s2); + *s1 = tmp; + return (*s1); +} + +int ft_getline(char **line) +{ + static char buff[BUFF_SIZE + 1] = "\0"; + char *ind; + int ret; + + if (line == NULL) + return (-1); + *line = NULL; + ind = NULL; + if (buff[0] == '\0') + ft_bzero(buff, BUFF_SIZE + 1); + while ((ret = read(0, buff, BUFF_SIZE)) == BUFF_SIZE && (ind = ft_strchr(buff, '\n')) == NULL) + { + if (*line == NULL) + { + if ((*line = ft_strdup(buff)) == NULL) + return (-1); + } + else if (*line != NULL) + if (supercat(line, &buff) == NULL) + { + ft_strdel(line); + return (-1); + } + ft_bzero(&buff, BUFF_SIZE + 1); + } + if (ind != NULL || (ind == NULL && (ind = ft_strchr(buff, '\n')) != NULL)) + *ind = '\0'; + if (*line == NULL) + { + if ((*line = ft_strdup(buff)) == NULL) + return (-1); + } + else if (*line != NULL) + { + printf("lengths %zu %zu\n", ft_strlen(*line), ft_strlen(buff)); + if (supercat(line, &buff) == NULL) + { + ft_strdel(line); + return (-1); + } + } + if (ind == NULL) + ft_bzero(&buff, BUFF_SIZE + 1); + if (ind != NULL && ind < &(buff[BUFF_SIZE])) + ft_memmove(buff, ind + 1, ft_strlen(ind + 1)); + return (*line != NULL && ret != 0); +} diff --git a/ft_printf.c b/ft_printf.c new file mode 100644 index 0000000..b589f14 --- /dev/null +++ b/ft_printf.c @@ -0,0 +1,91 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_printf.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: klebon +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/04/28 22:27:58 by klebon #+# #+# */ +/* Updated: 2019/02/19 18:11:54 by tmaze ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libftprintf.h" + +void init_handler_tab(char *(*t[16])(t_conv *, va_list)) +{ + t[d] = &handle_output_i_d; + t[D] = &handle_output_i_d; + t[i] = &handle_output_i_d; + t[x] = &handle_output_hexa; + t[X] = &handle_output_hexa; + t[p] = &handle_output_hexa; + t[o] = &handle_output_oct; + t[O] = &handle_output_oct; + t[u] = handle_output_u; + t[U] = handle_output_u; + t[c] = &handle_output_char; + t[C] = &handle_output_wchar; + t[s] = &handle_output_str; + t[S] = &handle_output_wstr; + t[percent] = &handle_output_char; + t[f] = &handle_output_float; +} + +void clean_mem(t_conv *field, va_list ap) +{ + free(field); + va_end(ap); +} + +int handle_conv(const char **str, t_conv *field, va_list ap, int *nb_print) +{ + char *(*handler[16])(t_conv *, va_list); + + init_handler_tab(handler); + (*str)++; + if (check_fields(str, ap, field)) + { + if (!(field->str = handler[field->fl_type](field, ap))) + { + clean_mem(field, ap); + return (0); + } + write(1, field->str, field->str_size); + *nb_print += field->str_size; + free(field->str); + } + else + { + clean_mem(field, ap); + return (0); + } + return (1); +} + +int ft_printf(const char *format, ...) +{ + va_list ap; + const char *str; + int nb_print_chars; + t_conv *field; + + if (!(field = (t_conv *)malloc(sizeof(t_conv)))) + return (-1); + va_start(ap, format); + str = format; + nb_print_chars = 0; + while (str && *str) + { + if (*str != '%') + { + write(1, str, 1); + ++nb_print_chars; + } + else if (!(handle_conv(&str, field, ap, &nb_print_chars))) + return (-1); + ++str; + } + clean_mem(field, ap); + return (nb_print_chars); +} diff --git a/ft_printf_check_fields.c b/ft_printf_check_fields.c new file mode 100644 index 0000000..bab02e4 --- /dev/null +++ b/ft_printf_check_fields.c @@ -0,0 +1,142 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* check_fields.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: klebon +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/04/29 12:33:40 by klebon #+# #+# */ +/* Updated: 2019/02/17 18:58:27 by tmaze ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libftprintf.h" + +void check_flags(const char **str, t_conv *field) +{ + while (**str == '-' || **str == '+' || **str == '0' || **str == '#' + || **str == ' ') + { + if (**str == '-') + field->fl_minus = 1; + else if (**str == '+') + field->fl_plus = 1; + else if (**str == '0') + field->fl_zero = 1; + else if (**str == '#') + field->fl_hashtag = 1; + else if (**str == ' ') + field->fl_space = 1; + (*str)++; + } +} + +void check_width(const char **str, t_conv *field, va_list ap) +{ + int tmp; + + if (**str == '*') + { + tmp = va_arg(ap, int); + field->fl_witdth = (tmp < 0) ? -tmp : tmp; + if (tmp < 0) + field->fl_minus = 1; + (*str)++; + } + else + { + field->fl_witdth = 0; + while (**str >= '0' && **str <= '9') + { + field->fl_witdth *= 10; + field->fl_witdth += **str - '0'; + (*str)++; + } + } +} + +ssize_t check_precision(const char **str, t_conv *field, va_list ap) +{ + int tmp; + + if (**str == '.') + { + (*str)++; + if (**str == '*') + { + if ((tmp = va_arg(ap, int)) >= 0) + field->fl_prec = tmp; + (*str)++; + } + else if (**str >= '0' && **str <= '9') + { + field->fl_prec = 0; + while (**str >= '0' && **str <= '9') + { + field->fl_prec *= 10; + field->fl_prec += **str - '0'; + (*str)++; + } + } + else + field->fl_prec = 0; + } + return (1); +} + +void check_size(const char **str, t_conv *field) +{ + if (**str == 'h' || **str == 'l' || **str == 'j' || **str == 'z' + || **str == 'L') + { + if (**str == 'h' && *(*str + 1) == 'h') + { + field->fl_size = hh; + (*str)++; + } + else if (**str == 'h') + field->fl_size = h; + else if (**str == 'l' && *(*str + 1) == 'l') + { + field->fl_size = ll; + (*str)++; + } + else if (**str == 'l') + field->fl_size = l; + else if (**str == 'j') + field->fl_size = l; + else if (**str == 'z') + field->fl_size = l; + else if (**str == 'L') + field->fl_size = L; + (*str)++; + } +} + +ssize_t check_fields(const char **str, va_list ap, t_conv *field) +{ + init_struct_conv(field); + check_flags(str, field); + check_width(str, field, ap); + if (!(check_precision(str, field, ap))) + return (0); + check_size(str, field); + if (!(check_type_one(str, field)) || !(check_type_two(str, field))) + return (0); + if ((field->fl_type != d && field->fl_type != D && field->fl_type != i + && field->fl_type != f) || field->fl_plus == 1) + field->fl_space = 0; + if (field->fl_type < s && field->fl_prec != -1) + field->fl_zero = 0; + else if (field->fl_type < s && field->fl_prec == -1) + field->fl_prec = 1; + if (field->fl_type == C && field->fl_size == h) + field->fl_type = c; + if (field->fl_type == c && field->fl_size == l) + field->fl_type = C; + if (field->fl_type == S && field->fl_size == h) + field->fl_type = s; + if (field->fl_type == s && field->fl_size == l) + field->fl_type = S; + return (1); +} diff --git a/ft_printf_check_type.c b/ft_printf_check_type.c new file mode 100644 index 0000000..419eeae --- /dev/null +++ b/ft_printf_check_type.c @@ -0,0 +1,69 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* check_type.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: klebon +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/05/02 21:09:18 by klebon #+# #+# */ +/* Updated: 2019/02/14 16:30:45 by tmaze ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libftprintf.h" + +ssize_t check_type_one(const char **str, t_conv *field) +{ + if (**str == 'd' || **str == 'D' || **str == 'i' || **str == 'o' + || **str == 'u' || **str == 'x' || **str == 'X' || **str == 's' + || **str == 'S' || **str == 'c' || **str == 'C' || **str == 'U' + || **str == 'p' || **str == '%' || **str == 'O' || **str == 'f') + { + if (**str == 'd') + field->fl_type = d; + else if (**str == 'D') + field->fl_type = D; + else if (**str == 'i') + field->fl_type = i; + else if (**str == 'o') + field->fl_type = o; + else if (**str == 'u') + field->fl_type = u; + else if (**str == 'U') + field->fl_type = U; + else if (**str == 'x') + field->fl_type = x; + else if (**str == 'X') + field->fl_type = X; + return (1); + } + return (0); +} + +ssize_t check_type_two(const char **str, t_conv *field) +{ + if (**str == 'd' || **str == 'D' || **str == 'i' || **str == 'o' + || **str == 'u' || **str == 'x' || **str == 'X' || **str == 's' + || **str == 'S' || **str == 'c' || **str == 'C' || **str == 'U' + || **str == 'p' || **str == '%' || **str == 'O' || **str == 'f') + { + if (**str == 's') + field->fl_type = s; + else if (**str == 'S') + field->fl_type = S; + else if (**str == 'c') + field->fl_type = c; + else if (**str == 'C') + field->fl_type = C; + else if (**str == 'p') + field->fl_type = p; + else if (**str == '%') + field->fl_type = percent; + else if (**str == 'O') + field->fl_type = O; + else if (**str == 'f') + field->fl_type = f; + return (1); + } + return (0); +} diff --git a/ft_printf_tools.c b/ft_printf_tools.c new file mode 100644 index 0000000..77b3200 --- /dev/null +++ b/ft_printf_tools.c @@ -0,0 +1,49 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tools.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: klebon +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/05/02 21:49:45 by klebon #+# #+# */ +/* Updated: 2019/03/01 12:11:36 by tmaze ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libftprintf.h" + +void init_struct_conv(t_conv *field) +{ + field->fl_minus = 0; + field->fl_plus = 0; + field->fl_zero = 0; + field->fl_hashtag = 0; + field->fl_space = 0; + field->fl_witdth = 0; + field->fl_prec = -1; + field->fl_size = -1; + field->fl_type = -1; + field->str = NULL; + field->str_size = 0; +} + +char *ft_strnewb(size_t size) +{ + size_t i; + char *str; + + i = -1; + if (!(str = (char *)malloc(sizeof(char) * (size + 1)))) + return (NULL); + while (++i < (size + 1)) + str[i] = '\0'; + return (str); +} + +uint64_t dmod(long double nb, long double mod) +{ + uint64_t res; + + res = (uint64_t)(nb - mod * (uint64_t)(nb / mod)); + return (res); +} diff --git a/ft_printf_tools_char.c b/ft_printf_tools_char.c new file mode 100644 index 0000000..dd3124a --- /dev/null +++ b/ft_printf_tools_char.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tools_char.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: klebon +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/05/19 08:51:48 by klebon #+# #+# */ +/* Updated: 2018/10/30 12:35:10 by klebon ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libftprintf.h" + +char *handle_output_char(t_conv *field, va_list ap) +{ + char *output; + unsigned char c; + + if (field->fl_type == percent) + c = '%'; + else + c = (unsigned char)va_arg(ap, int); + field->str_size = (field->fl_witdth > 1) ? field->fl_witdth : 1; + if (!(output = ft_strnewb(field->str_size))) + return (NULL); + output[0] = c; + ft_align_wchar(output, field); + return (output); +} diff --git a/ft_printf_tools_float.c b/ft_printf_tools_float.c new file mode 100644 index 0000000..9f6ed69 --- /dev/null +++ b/ft_printf_tools_float.c @@ -0,0 +1,122 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_printf_tools_float.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tmaze +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/02/13 12:52:34 by tmaze #+# #+# */ +/* Updated: 2019/03/03 17:36:31 by tmaze ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libftprintf.h" + +void roundup(char *str, long double n, int i, int prec) +{ + int ret; + int len; + + ret = 1; + len = ft_strlen(str); + if ((int)n >= 5 && (n - (int)n) > 0.0) + { + while (i-- != 0 && ret == 1) + { + if (str[i] != '.' && str[i] + 1 > '9' && (ret = 1)) + str[i] = '0'; + else if (str[i] != '.' && !(ret = 0)) + str[i]++; + } + if (ret == 1 && (i = ft_strlen(str)) < 4980) + while (--i > 0) + str[i + 1] = str[i]; + str[0] = (ret == 1 && i < 4980) ? '1' : str[0]; + } + i = 0; + while (str[i] && str[i] != '.') + i++; + i += prec + 1; + while (i < len) + str[i++] = '\0'; +} + +void getint(char *str, long double n, int *i) +{ + uint64_t nb; + long double div; + + nb = n; + div = 1; + while ((nb / div) >= 10) + div *= 10; + nb /= div; + while (*i < 4935 && div != 0) + { + str[*i] = (int)nb + '0'; + div = (div == 1) ? 0 : (div / 10); + nb = dmod((n / div), 10); + (*i)++; + } +} + +char *getnbrstr(long double nb, t_conv *field) +{ + char str[4980]; + int i; + int j; + + ft_bzero(str, 4980); + nb = nb * ((nb < 0.0) ? -1 : 1); + i = 0; + getint(str, nb, &i); + j = 0; + if (field->fl_prec > 0 || field->fl_hashtag) + str[i++] = '.'; + nb = (nb - (uint64_t)nb) * ((nb < 0.0) ? -1 : 1) * 10; + while (j < field->fl_prec && i + j < 4980) + { + str[i + j] = (uint64_t)nb + '0'; + nb = (nb - (uint64_t)nb) * 10; + j++; + } + i += j; + roundup(str, nb, i, field->fl_prec); + return (ft_strdup(str)); +} + +void set_strf(t_conv *f, char *nbrstr, long double nb, int pad) +{ + if (!f->fl_minus && !f->fl_zero) + ft_memset(f->str, ' ', (pad > 0) ? pad : 0); + if (nb < 0.0) + f->str[ft_strlen(f->str)] = '-'; + else if (f->fl_plus || f->fl_space) + f->str[ft_strlen(f->str)] = (f->fl_plus) ? '+' : ' '; + if (!f->fl_minus && f->fl_zero) + ft_memset(&f->str[ft_strlen(f->str)], '0', (pad > 0) ? pad : 0); + ft_strcat(f->str, nbrstr); + if (f->fl_minus) + ft_memset(&f->str[ft_strlen(f->str)], ' ', (pad > 0) ? pad : 0); +} + +char *handle_output_float(t_conv *field, va_list ap) +{ + long double nb; + int pad; + int size; + char *nbrstr; + + if (field->fl_size == L) + nb = (long double)va_arg(ap, long double); + else + nb = (long double)va_arg(ap, double); + field->fl_prec = (field->fl_prec == -1) ? 6 : field->fl_prec; + nbrstr = getnbrstr(nb, field); + size = set_malloc_sizef(nb, nbrstr, field); + pad = field->str_size - size; + if ((field->str = ft_strnewb(field->str_size)) != NULL) + set_strf(field, nbrstr, nb, pad); + ft_strdel(&nbrstr); + return (field->str); +} diff --git a/ft_printf_tools_hexa.c b/ft_printf_tools_hexa.c new file mode 100644 index 0000000..d7ee5c6 --- /dev/null +++ b/ft_printf_tools_hexa.c @@ -0,0 +1,120 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tools_hexa.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: klebon +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/05/13 19:58:30 by klebon #+# #+# */ +/* Updated: 2018/10/01 15:37:27 by klebon ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libftprintf.h" + +char *handler_hexa(uintmax_t nb, t_conv *field) +{ + int size; + uintmax_t n; + char *str; + + size = set_precision_sizex(nb, field); + set_malloc_sizeh(nb, field); + if (!(str = ft_strnewb(field->str_size))) + return (NULL); + n = nb; + while (n) + { + str[--size] = (field->fl_type == X) ? "0123456789ABCDEF"[n % 16] + : "0123456789abcdef"[n % 16]; + n /= 16; + } + while (--size >= 0 && field->fl_prec) + str[size] = '0'; + if (field->fl_hashtag) + str[1] = (field->fl_type == X) ? 'X' : 'x'; + if (field->fl_hashtag) + str[0] = '0'; + ft_align_hex(str, field); + return (str); +} + +void ft_align_hex_zero(char *str, t_conv *field) +{ + int i; + int len; + + i = 0; + len = (int)ft_strlen(str); + if (field->fl_hashtag == 0 || (field->fl_hashtag == 1 + && field->fl_zero == 0)) + { + ft_memmove(str + (field->str_size - len), str, len); + while (i < field->str_size - len) + str[i++] = (field->fl_zero) ? '0' : ' '; + } + else + { + i = 1; + ft_memmove(str + (field->str_size - len + 2), str + 2, len - 2); + while (++i < field->str_size - len + 2) + str[i] = '0'; + } +} + +void ft_align_hex(char *str, t_conv *field) +{ + int i; + + i = 0; + if ((int)(ft_strlen(str)) < field->str_size) + { + if (field->fl_minus == 1) + { + while (str[i]) + i++; + while (i < field->str_size) + str[i++] = ' '; + } + else + { + ft_align_hex_zero(str, field); + } + } +} + +char *select_hexa_handler(t_conv *field, va_list ap) +{ + uintmax_t tmp; + + if (field->fl_size == h) + tmp = (uintmax_t)(short unsigned int)va_arg(ap, unsigned int); + else if (field->fl_size == hh) + tmp = (uintmax_t)(unsigned char)va_arg(ap, unsigned int); + else if (field->fl_size == l) + tmp = (uintmax_t)va_arg(ap, long unsigned int); + else if (field->fl_size == ll) + tmp = (uintmax_t)va_arg(ap, unsigned long long int); + else if (field->fl_size == j) + tmp = va_arg(ap, uintmax_t); + else if (field->fl_size == z) + tmp = (uintmax_t)va_arg(ap, size_t); + else + tmp = (uintmax_t)va_arg(ap, unsigned int); + if (tmp == 0 && field->fl_type != p) + field->fl_hashtag = 0; + return (handler_hexa(tmp, field)); +} + +char *handle_output_hexa(t_conv *field, va_list ap) +{ + char *output; + + if (field->fl_type == p) + { + field->fl_hashtag = 1; + field->fl_size = j; + } + output = select_hexa_handler(field, ap); + return (output); +} diff --git a/ft_printf_tools_int.c b/ft_printf_tools_int.c new file mode 100644 index 0000000..b01486c --- /dev/null +++ b/ft_printf_tools_int.c @@ -0,0 +1,113 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tools_int.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: klebon +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/05/10 14:02:42 by klebon #+# #+# */ +/* Updated: 2018/10/30 11:51:59 by klebon ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libftprintf.h" + +char *handler_int(uintmax_t nb, t_conv *field) +{ + int size; + uintmax_t n; + char *str; + + size = set_precision_sizes(nb, field); + set_malloc_sizes(nb, field); + if (!(str = ft_strnewb(field->str_size))) + return (NULL); + n = ((intmax_t)nb >= 0) ? (uintmax_t)nb : -(uintmax_t)nb; + while (n) + { + str[--size] = n % 10 + '0'; + n /= 10; + } + while (--size >= 0 && field->fl_prec) + str[size] = '0'; + if ((intmax_t)nb < 0) + str[0] = '-'; + else if (field->fl_plus || field->fl_space) + str[0] = (field->fl_plus) ? '+' : ' '; + ft_align_str(str, field); + return (str); +} + +void ft_align_str_zero(char *str, t_conv *field) +{ + int i; + int len; + + i = 0; + len = (int)ft_strlen(str); + if (field->fl_zero == 0 + || (str[0] != '-' && str[0] != '+' && str[0] != ' ')) + { + ft_memmove(str + (field->str_size - len), str, len); + while (i < field->str_size - len) + str[i++] = (field->fl_zero && field->fl_prec == 1) ? '0' : ' '; + } + else + { + ft_memmove(str + (field->str_size - len + 1), str + 1, len - 1); + while (++i < field->str_size - len + 1) + str[i] = '0'; + } +} + +void ft_align_str(char *str, t_conv *field) +{ + int i; + + i = 0; + if ((int)(ft_strlen(str)) < field->str_size) + { + if (field->fl_minus == 1) + { + while (str[i]) + i++; + while (i < field->str_size) + str[i++] = ' '; + } + else + { + ft_align_str_zero(str, field); + } + } +} + +char *select_int_handler(t_conv *field, va_list ap) +{ + uintmax_t tmp; + + if (field->fl_size == h) + tmp = (uintmax_t)(short int)va_arg(ap, int); + else if (field->fl_size == hh) + tmp = (uintmax_t)(char)va_arg(ap, int); + else if (field->fl_size == l) + tmp = (uintmax_t)va_arg(ap, long int); + else if (field->fl_size == ll) + tmp = (uintmax_t)va_arg(ap, long long int); + else if (field->fl_size == j) + tmp = (uintmax_t)va_arg(ap, intmax_t); + else if (field->fl_size == z) + tmp = (uintmax_t)va_arg(ap, ssize_t); + else + tmp = (uintmax_t)va_arg(ap, int); + return (handler_int(tmp, field)); +} + +char *handle_output_i_d(t_conv *field, va_list ap) +{ + char *output; + + if (field->fl_type == D) + field->fl_size = l; + output = select_int_handler(field, ap); + return (output); +} diff --git a/ft_printf_tools_lenght.c b/ft_printf_tools_lenght.c new file mode 100644 index 0000000..167654f --- /dev/null +++ b/ft_printf_tools_lenght.c @@ -0,0 +1,50 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tools_lenght.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: klebon +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/10/01 15:40:34 by klebon #+# #+# */ +/* Updated: 2018/10/01 15:41:28 by klebon ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libftprintf.h" + +unsigned int ft_bin_size(unsigned int nb) +{ + unsigned int n; + unsigned int size; + + n = nb; + size = 1; + while (n /= 2) + size++; + return (size); +} + +int ft_wstrlen(const wint_t *str) +{ + int i; + int len; + + i = 0; + len = 0; + while (str[i]) + { + if (str[i] < 0 || (MB_CUR_MAX == 1 && str[i] > 0xFF) + || (str[i] >= 0xD800 && str[i] <= 0xDFFF) || str[i] > 0x10FFFF) + return (-1); + else if (str[i] <= 0x7F || (MB_CUR_MAX == 1 && str[i] <= 0xFF)) + len += 1; + else if (str[i] <= 0x7FF) + len += 2; + else if (str[i] <= 0xFFFF) + len += 3; + else if (str[i] <= 0x10FFFF) + len += 4; + ++i; + } + return (len); +} diff --git a/ft_printf_tools_malloc_size.c b/ft_printf_tools_malloc_size.c new file mode 100644 index 0000000..e6c5c3a --- /dev/null +++ b/ft_printf_tools_malloc_size.c @@ -0,0 +1,79 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tools_malloc_size.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: klebon +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/10/01 13:43:37 by klebon #+# #+# */ +/* Updated: 2019/02/21 12:36:37 by tmaze ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libftprintf.h" + +void set_malloc_sizes(uintmax_t nb, t_conv *field) +{ + uintmax_t tmp; + + if (nb == 0 && field->fl_prec == 0) + field->str_size = 0; + else + field->str_size = 1; + tmp = ((intmax_t)nb >= 0) ? (uintmax_t)nb : -(uintmax_t)nb; + while (tmp /= 10) + ++field->str_size; + field->str_size = (field->str_size < field->fl_prec) + ? field->fl_prec : field->str_size; + field->str_size += ((intmax_t)nb < 0 || field->fl_plus + || field->fl_space) ? 1 : 0; + field->str_size = (field->str_size < field->fl_witdth) + ? field->fl_witdth : field->str_size; +} + +void set_malloc_sizeh(uintmax_t nb, t_conv *field) +{ + uintmax_t tmp; + + if (nb == 0 && field->fl_prec == 0) + field->str_size = 0; + else + field->str_size = 1; + tmp = nb; + while (tmp /= 16) + field->str_size++; + field->str_size = (field->str_size < field->fl_prec) + ? field->fl_prec : field->str_size; + field->str_size += (field->fl_hashtag) ? 2 : 0; + field->str_size = (field->str_size < field->fl_witdth) + ? field->fl_witdth : field->str_size; +} + +void set_malloc_sizeo(uintmax_t nb, t_conv *field) +{ + uintmax_t tmp; + + if (nb == 0) + field->str_size = 0; + else + field->str_size = 1; + tmp = nb; + while (tmp /= 8) + ++field->str_size; + field->str_size += (field->fl_hashtag) ? 1 : 0; + field->str_size = (field->str_size < field->fl_prec) + ? field->fl_prec : field->str_size; + field->str_size = (field->str_size < field->fl_witdth) + ? field->fl_witdth : field->str_size; +} + +int set_malloc_sizef(long double nb, char *nbrstr, t_conv *field) +{ + int size; + + size = ft_strlen(nbrstr); + if (nb < 0.0 || field->fl_plus || field->fl_space) + size++; + field->str_size = (field->fl_witdth > size) ? field->fl_witdth : size; + return (size); +} diff --git a/ft_printf_tools_oct.c b/ft_printf_tools_oct.c new file mode 100644 index 0000000..ab4afc7 --- /dev/null +++ b/ft_printf_tools_oct.c @@ -0,0 +1,110 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tools_oct.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: klebon +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/05/13 20:13:28 by klebon #+# #+# */ +/* Updated: 2018/10/01 15:38:13 by klebon ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libftprintf.h" + +char *handler_oct(uintmax_t nb, t_conv *field) +{ + int size; + uintmax_t n; + char *str; + + size = set_precision_sizeo(nb, field); + set_malloc_sizeo(nb, field); + if (!(str = ft_strnewb(field->str_size))) + return (NULL); + n = nb; + while (n) + { + str[--size] = n % 8 + '0'; + n /= 8; + } + while (--size >= 0 && field->fl_prec) + str[size] = '0'; + if (field->fl_hashtag) + str[0] = '0'; + ft_align_oct(str, field); + return (str); +} + +void ft_align_oct_zero(char *str, t_conv *field) +{ + int i; + int len; + + i = 0; + len = (int)ft_strlen(str); + if (field->fl_zero == 0 || field->fl_hashtag == 0) + { + ft_memmove(str + (field->str_size - len), str, len); + while (i < field->str_size - len) + str[i++] = (field->fl_zero) ? '0' : ' '; + } + else + { + ft_memmove(str + (field->str_size - len + 1), str + 1, len - 1); + while (++i < field->str_size - len + 1) + str[i] = '0'; + } +} + +void ft_align_oct(char *str, t_conv *field) +{ + int i; + + i = 0; + if ((int)(ft_strlen(str)) < field->str_size) + { + if (field->fl_minus == 1) + { + while (str[i]) + i++; + while (i < field->str_size) + str[i++] = ' '; + } + else + { + ft_align_oct_zero(str, field); + } + } +} + +char *select_oct_handler(t_conv *field, va_list ap) +{ + uintmax_t tmp; + + if (field->fl_size == h) + tmp = (uintmax_t)(short unsigned int)va_arg(ap, unsigned int); + else if (field->fl_size == hh) + tmp = (uintmax_t)(unsigned char)va_arg(ap, unsigned int); + else if (field->fl_size == l) + tmp = (uintmax_t)va_arg(ap, long unsigned int); + else if (field->fl_size == ll) + tmp = (uintmax_t)va_arg(ap, unsigned long long int); + else if (field->fl_size == j) + tmp = va_arg(ap, uintmax_t); + else if (field->fl_size == z) + tmp = (uintmax_t)va_arg(ap, size_t); + else + tmp = (uintmax_t)va_arg(ap, unsigned int); + return (handler_oct(tmp, field)); +} + +char *handle_output_oct(t_conv *field, va_list ap) +{ + char *output; + + if (field->fl_type == O) + field->fl_size = l; + output = select_oct_handler(field, ap); + return (output); +} diff --git a/ft_printf_tools_prec_size.c b/ft_printf_tools_prec_size.c new file mode 100644 index 0000000..18d9c02 --- /dev/null +++ b/ft_printf_tools_prec_size.c @@ -0,0 +1,97 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tools_prec_size.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: klebon +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/10/01 15:36:42 by klebon #+# #+# */ +/* Updated: 2018/10/01 15:39:43 by klebon ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libftprintf.h" + +int set_precision_sizex(uintmax_t nb, t_conv *field) +{ + uintmax_t tmp; + int size; + + if (nb == 0 && field->fl_prec == 0) + size = 0; + else + size = 1; + tmp = nb; + while (tmp /= 16) + ++size; + size = (size < field->fl_prec) ? field->fl_prec : size; + size += (field->fl_hashtag) ? 2 : 0; + return (size); +} + +int set_precision_sizes(uintmax_t nb, t_conv *field) +{ + uintmax_t tmp; + int size; + + if (nb == 0 && field->fl_prec == 0) + size = 0; + else + size = 1; + tmp = ((intmax_t)nb >= 0) ? (uintmax_t)nb : -(uintmax_t)nb; + while (tmp /= 10) + ++size; + size = (size < field->fl_prec) ? field->fl_prec : size; + size += ((intmax_t)nb < 0 || field->fl_plus || field->fl_space) ? 1 : 0; + return (size); +} + +int set_precision_sizeo(uintmax_t nb, t_conv *field) +{ + uintmax_t tmp; + int size; + + if (nb == 0 && field->fl_prec == 0) + size = 0; + else if (nb == 0) + { + size = 0; + field->fl_hashtag = 0; + } + else + size = 1; + tmp = nb; + while (tmp /= 8) + ++size; + size += (field->fl_hashtag) ? 1 : 0; + size = (size < field->fl_prec) ? field->fl_prec : size; + return (size); +} + +int set_prec_size_wstr(const wint_t *str, t_conv *field) +{ + int i; + int tmp; + + i = 0; + field->str_size = 0; + while (str[i] && (field->str_size < field->fl_prec)) + { + tmp = field->str_size; + if (str[i] < 0 || (MB_CUR_MAX == 1 && str[i] > 0xFF) + || (str[i] >= 0xD800 && str[i] <= 0xDFFF) || str[i] > 0x10FFFF) + return (0); + else if (str[i] <= 0x7F || (MB_CUR_MAX == 1 && str[i] <= 0xFF)) + field->str_size += (field->str_size + 1 <= field->fl_prec) ? 1 : 0; + else if (str[i] <= 0x7FF) + field->str_size += (field->str_size + 2 <= field->fl_prec) ? 2 : 0; + else if (str[i] <= 0xFFFF) + field->str_size += (field->str_size + 3 <= field->fl_prec) ? 3 : 0; + else if (str[i] <= 0x10FFFF) + field->str_size += (field->str_size + 4 <= field->fl_prec) ? 4 : 0; + if (tmp == field->str_size) + return (1); + ++i; + } + return (1); +} diff --git a/ft_printf_tools_str.c b/ft_printf_tools_str.c new file mode 100644 index 0000000..cd1293d --- /dev/null +++ b/ft_printf_tools_str.c @@ -0,0 +1,64 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_printf_tools_str.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: klebon +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/05/19 09:05:22 by klebon #+# #+# */ +/* Updated: 2019/03/03 09:12:19 by klebon ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libftprintf.h" + +void ft_align_wstr(char *str, t_conv *field) +{ + int i; + int len; + + i = 0; + if (field->fl_witdth >= 1) + { + if (field->fl_minus) + { + while (str[i]) + i++; + while (i < field->str_size) + str[i++] = ' '; + } + else + { + len = (int)ft_strlen(str); + ft_memmove(str + (field->str_size - len), str, len); + while (i < (field->str_size - len)) + { + str[i] = ' '; + i++; + } + } + } +} + +char *handle_output_str(t_conv *field, va_list ap) +{ + char *output; + int len; + const char *str; + + str = va_arg(ap, const char *); + if (str == NULL) + str = "(null)"; + len = (int)ft_strlen(str); + if (field->fl_prec != -1) + len = (len > field->fl_prec) ? field->fl_prec : len; + field->str_size = (field->fl_witdth > len) ? field->fl_witdth : len; + if (!(output = ft_strnewb(field->str_size))) + return (NULL); + if (field->fl_prec == -1) + ft_strcpy_s(output, str); + else + ft_strncpy_s(output, str, len); + ft_align_wstr(output, field); + return (output); +} diff --git a/ft_printf_tools_unsigned_int.c b/ft_printf_tools_unsigned_int.c new file mode 100644 index 0000000..355f8f3 --- /dev/null +++ b/ft_printf_tools_unsigned_int.c @@ -0,0 +1,99 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tools_unsigned_int.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: klebon +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/05/13 19:43:31 by klebon #+# #+# */ +/* Updated: 2018/05/25 18:56:39 by klebon ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libftprintf.h" + +void set_malloc_sizeu(uintmax_t nb, t_conv *field) +{ + uintmax_t tmp; + + if (nb == 0 && field->fl_prec == 0) + field->str_size = 0; + else + field->str_size = 1; + tmp = nb; + while (tmp /= 10) + ++field->str_size; + field->str_size = (field->str_size < field->fl_prec) + ? field->fl_prec : field->str_size; + field->str_size = (field->str_size < field->fl_witdth) + ? field->fl_witdth : field->str_size; +} + +int set_precision_sizeu(uintmax_t nb, t_conv *field) +{ + uintmax_t tmp; + int size; + + if (nb == 0 && field->fl_prec == 0) + size = 0; + else + size = 1; + tmp = nb; + while (tmp /= 10) + ++size; + size = (size < field->fl_prec) ? field->fl_prec : size; + return (size); +} + +char *handler_uns(uintmax_t nb, t_conv *field) +{ + int size; + uintmax_t n; + char *str; + + size = set_precision_sizeu(nb, field); + set_malloc_sizeu(nb, field); + if (!(str = ft_strnewb(field->str_size))) + return (NULL); + n = nb; + while (n) + { + str[--size] = n % 10 + '0'; + n /= 10; + } + while (--size >= 0 && field->fl_prec) + str[size] = '0'; + ft_align_str(str, field); + return (str); +} + +char *select_uns_int_handler(t_conv *field, va_list ap) +{ + uintmax_t tmp; + + if (field->fl_size == h) + tmp = (uintmax_t)(short unsigned int)va_arg(ap, unsigned int); + else if (field->fl_size == hh) + tmp = (uintmax_t)(unsigned char)va_arg(ap, unsigned int); + else if (field->fl_size == l) + tmp = (uintmax_t)va_arg(ap, long unsigned int); + else if (field->fl_size == ll) + tmp = (uintmax_t)va_arg(ap, unsigned long long int); + else if (field->fl_size == j) + tmp = va_arg(ap, uintmax_t); + else if (field->fl_size == z) + tmp = (uintmax_t)va_arg(ap, size_t); + else + tmp = (uintmax_t)va_arg(ap, unsigned int); + return (handler_uns(tmp, field)); +} + +char *handle_output_u(t_conv *field, va_list ap) +{ + char *output; + + if (field->fl_type == U) + field->fl_size = l; + output = select_uns_int_handler(field, ap); + return (output); +} diff --git a/ft_printf_tools_wchar_t.c b/ft_printf_tools_wchar_t.c new file mode 100644 index 0000000..f6d85ef --- /dev/null +++ b/ft_printf_tools_wchar_t.c @@ -0,0 +1,113 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tools_wchar_t.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: klebon +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/05/18 18:10:11 by klebon #+# #+# */ +/* Updated: 2018/10/01 15:40:54 by klebon ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libftprintf.h" + +/* +** I have to handle minus, width +*/ + +void ft_align_wchar(char *str, t_conv *field) +{ + int i; + int len; + + len = (int)ft_strlen(str); + len = (len) ? len : 1; + if (len < field->str_size) + { + if (field->fl_minus == 1) + { + i = 1; + while (str[i]) + ++i; + while (i < field->str_size) + str[i++] = ' '; + } + else + { + i = 0; + ft_memmove(str + (field->str_size - len), str, len); + while (i < field->str_size - len) + str[i++] = (field->fl_zero) ? '0' : ' '; + } + } +} + +char *handler_2oct_char(wint_t c, t_conv *field) +{ + char *output; + + field->str_size = (field->fl_witdth > 2) ? field->fl_witdth : 2; + if (!(output = ft_strnewb(field->str_size))) + return (NULL); + output[0] = (c >> 6) + 0xC0; + output[1] = (c & 0x3F) + 0x80; + ft_align_wchar(output, field); + return (output); +} + +char *handler_3oct_char(wint_t c, t_conv *field) +{ + char *output; + + field->str_size = (field->fl_witdth > 3) ? field->fl_witdth : 3; + if (!(output = ft_strnewb(field->str_size))) + return (NULL); + output[0] = (c >> 12) + 0xE0; + output[1] = ((c >> 6) & 0x3F) + 0x80; + output[2] = (c & 0x3F) + 0x80; + ft_align_wchar(output, field); + return (output); +} + +char *handler_4oct_char(wint_t c, t_conv *field) +{ + char *output; + + field->str_size = (field->fl_witdth > 4) ? field->fl_witdth : 4; + if (!(output = ft_strnewb(field->str_size))) + return (NULL); + output[0] = (c >> 18) + 0xF0; + output[1] = ((c >> 12) & 0x3F) + 0x80; + output[2] = ((c >> 6) & 0x3F) + 0x80; + output[3] = (c & 0x3F) + 0x80; + ft_align_wchar(output, field); + return (output); +} + +char *handle_output_wchar(t_conv *field, va_list ap) +{ + char *output; + wint_t c; + + c = (wint_t)va_arg(ap, wint_t); + if (c < 0 || (MB_CUR_MAX == 1 && c > 0xFF) || (c >= 0xD800 && c <= 0xDFFF)) + return (NULL); + else if (c <= 0x7F || (MB_CUR_MAX == 1 && c <= 0xFF)) + { + field->str_size = (field->fl_witdth > 1) ? field->fl_witdth : 1; + if (!(output = ft_strnewb(field->str_size))) + return (NULL); + output[0] = (char)c; + ft_align_wchar(output, field); + } + else if (c <= 0x7FF) + output = handler_2oct_char(c, field); + else if (c <= 0xFFFF) + output = handler_3oct_char(c, field); + else if (c <= 0x10FFFF) + output = handler_4oct_char(c, field); + else + return (NULL); + return (output); +} diff --git a/ft_printf_tools_wstr.c b/ft_printf_tools_wstr.c new file mode 100644 index 0000000..c74f216 --- /dev/null +++ b/ft_printf_tools_wstr.c @@ -0,0 +1,89 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tools_wstr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: klebon +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/05/23 19:48:06 by klebon #+# #+# */ +/* Updated: 2018/10/01 15:41:10 by klebon ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libftprintf.h" + +void handler_2oct_wstr(wint_t c, char *output, int *i) +{ + output[(*i)++] = (c >> 6) + 0xC0; + output[(*i)++] = (c & 0x3F) + 0x80; +} + +void handler_3oct_wstr(wint_t c, char *output, int *i) +{ + output[(*i)++] = (c >> 12) + 0xE0; + output[(*i)++] = ((c >> 6) & 0x3F) + 0x80; + output[(*i)++] = (c & 0x3F) + 0x80; +} + +void handler_4oct_wstr(wint_t c, char *output, int *i) +{ + output[(*i)++] = (c >> 18) + 0xF0; + output[(*i)++] = ((c >> 12) & 0x3F) + 0x80; + output[(*i)++] = ((c >> 6) & 0x3F) + 0x80; + output[(*i)++] = (c & 0x3F) + 0x80; +} + +void convert_wstr_to_str(const wint_t *str, char *output, t_conv *field) +{ + int i; + int j; + int tmp; + + i = 0; + j = 0; + while (str[i] && j <= field->fl_prec) + { + tmp = j; + if (j + 1 <= field->fl_prec + && (str[i] <= 0x7F || (MB_CUR_MAX == 1 && str[i] <= 0xFF))) + output[j++] = (char)str[i]; + else if (j + 2 <= field->fl_prec && str[i] <= 0x7FF) + handler_2oct_wstr(str[i], output, &j); + else if (j + 3 <= field->fl_prec && str[i] <= 0xFFFF) + handler_3oct_wstr(str[i], output, &j); + else if (j + 4 <= field->fl_prec) + handler_4oct_wstr(str[i], output, &j); + ++i; + if (tmp == j) + break ; + } +} + +char *handle_output_wstr(t_conv *field, va_list ap) +{ + char *output; + const wint_t *str; + + str = (wint_t *)va_arg(ap, const wint_t *); + if (str == NULL) + str = L"(null)"; + if (field->fl_prec != -1) + { + if (set_prec_size_wstr(str, field) == 0) + return (NULL); + } + else + { + if ((field->str_size = ft_wstrlen(str)) == -1) + return (NULL); + } + if (field->fl_prec == -1) + field->fl_prec = field->str_size; + if (field->fl_witdth > field->str_size) + field->str_size += (field->fl_witdth - field->str_size); + if (!(output = ft_strnewb(field->str_size))) + return (NULL); + convert_wstr_to_str(str, output, field); + ft_align_wstr(output, field); + return (output); +} diff --git a/ft_strjoin.c b/ft_strjoin.c index c44d528..768d3f3 100644 --- a/ft_strjoin.c +++ b/ft_strjoin.c @@ -6,7 +6,7 @@ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2018/04/07 16:30:47 by tmaze #+# #+# */ -/* Updated: 2018/04/10 14:11:36 by tmaze ### ########.fr */ +/* Updated: 2019/03/07 19:05:27 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/libft.h b/libft.h index 2f4a973..bbb6e16 100644 --- a/libft.h +++ b/libft.h @@ -6,7 +6,7 @@ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2018/04/08 00:12:36 by tmaze #+# #+# */ -/* Updated: 2019/02/27 12:23:14 by tmaze ### ########.fr */ +/* Updated: 2019/03/07 15:38:26 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,10 @@ # include # include # include +# include +# include +# include +# include # define FT_RESET "\x1b[0m" # define FT_BOLD "\x1b[1m" @@ -58,6 +62,166 @@ typedef struct s_list # define BUFF_SIZE 30 +enum e_size +{ + h, + hh, + l, + ll, + j, + z, + L +}; + +enum e_type +{ + p, + d, + i, + D, + o, + O, + u, + x, + X, + U, + s, + S, + c, + C, + percent, + f +}; + +typedef struct s_conv +{ + int fl_minus; + int fl_plus; + int fl_zero; + int fl_hashtag; + int fl_space; + int fl_witdth; + int fl_prec; + enum e_size fl_size; + enum e_type fl_type; + char *str; + int str_size; +} t_conv; + +/* +** Print functions +*/ + +int ft_printf(const char *format, ...); +void ft_putchar(char c); +void ft_putnbr(int n); +void ft_putstr(char const *s); + +/* +** ft_printf tools +*/ + +void init_struct_conv(t_conv *field); +void ft_align_str_zero(char *str, t_conv *field); +void ft_align_str(char *str, t_conv *field); +void set_malloc_sizes(uintmax_t nb, t_conv *field); +void set_malloc_sizeu(uintmax_t nb, t_conv *field); +void set_malloc_sizeo(uintmax_t nb, t_conv *field); +void set_malloc_sizeu(uintmax_t nb, t_conv *field); +int set_malloc_sizef(long double nb, char *nbrstr, t_conv *field); +void init_handler_tab(char *(*f[14])(t_conv *, va_list)); +int ft_wstrlen(const wint_t *str); +uint64_t dmod(long double nb, long double mod); + +/* +** Check Flags +*/ + +void check_flags(const char **str, t_conv *field); +void check_width(const char **str, t_conv *field, va_list ap); +ssize_t check_precision(const char **str, t_conv *field, va_list ap); +void check_size(const char **str, t_conv *field); +ssize_t check_type_one(const char **str, t_conv *field); +ssize_t check_type_two(const char **str, t_conv *field); +ssize_t check_fields(const char **str, va_list ap, t_conv *field); + +/* +** Handle type i and d +*/ + +char *handler_int(uintmax_t nb, t_conv *field); +char *select_int_handler(t_conv *field, va_list ap); +char *handle_output_i_d(t_conv *field, va_list ap); + +/* +** Handle type u +*/ + +char *select_uns_int_handler(t_conv *field, va_list ap); +char *handle_output_u(t_conv *field, va_list ap); +char *handler_uns(uintmax_t nb, t_conv *field); + +/* +** Handle type x and X +*/ + +char *handler_hexa(uintmax_t nb, t_conv *field); +char *select_hexa_handler(t_conv *field, va_list ap); +char *handle_output_hexa(t_conv *field, va_list ap); +void ft_align_hex_zero(char *str, t_conv *field); +void ft_align_hex(char *str, t_conv *field); +int set_precision_sizex(uintmax_t nb, t_conv *field); +void set_malloc_sizeh(uintmax_t nb, t_conv *field); + +/* +** Handle type o +*/ + +char *handler_oct(uintmax_t nb, t_conv *field); +char *select_oct_handler(t_conv *field, va_list ap); +char *handle_output_oct(t_conv *field, va_list ap); +void ft_align_oct_zero(char *str, t_conv *field); +void ft_align_oct(char *str, t_conv *field); +int set_precision_sizeo(uintmax_t nb, t_conv *field); + +/* +** Handle type c +*/ + +char *handle_output_char(t_conv *field, va_list ap); + +/* +** Handle type C +*/ + +unsigned int ft_bin_size(unsigned int nb); +void ft_align_wchar(char *str, t_conv *field); +char *handler_2oct_char(wint_t c, t_conv *field); +char *handler_3oct_char(wint_t c, t_conv *field); +char *handler_4oct_char(wint_t c, t_conv *field); +char *handle_output_wchar(t_conv *field, va_list ap); + +/* +** Handle type s +*/ + +char *handle_output_str(t_conv *field, va_list ap); +void ft_align_wstr(char *str, t_conv *field); +int set_precision_sizes(uintmax_t nb, t_conv *field); + +/* +** Handle type S +*/ + +char *handle_output_wstr(t_conv *field, va_list ap); +int set_prec_size_wstr(const wint_t *str, t_conv *field); + +/* +** Handle type f +*/ + +char *handle_output_float(t_conv *field, va_list ap); + /* ** fonctions obligatoires */ @@ -183,5 +347,6 @@ int ft_iswhitespace(char c); int ft_hasdigit(char *s); char **ft_strsplitwhitespace(char *s); int ft_atois(const char *str, int *nb); +int ft_getline(char **line); #endif