/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* main.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: gbaconni@student.42lausanne.ch +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/04/13 06:58:46 by gbaconni #+# #+# */ /* Updated: 2022/04/29 08:23:07 by gbaconni ### lausanne.ch */ /* */ /* ************************************************************************** */ #include // printf #include // strlen #include // isdigit #include // assert #include "libftprintf/libftprintf.h" char *ft_fmtsplit(char **fmt) { char *format; char *start; char *end; int len; format = NULL; start = *fmt; end = *fmt; if (start == NULL) return (NULL); if (*end == '%') if (*end++ == '%') end++; while (*end != '\0' && *end != '%') end++; len = end - start; format = (char *) calloc(len + 1, sizeof(char)); if (format == NULL) return (NULL); strncpy(format, start, len); if (*end == '\0') *fmt = NULL; else *fmt += len; return (format); } int _printf(int (*f)(const char *restrict, ...), \ char *format, char *arg) { int ret; char c; ret = 0; if (arg == NULL) return (ret); c = *(format + 1 + ft_skipchars(format + 1, "0123456789# +")); if (c == 'c') ret = (*f)(format, *arg); else if (c == 's') ret = (*f)(format, arg); else if (c == 'p') ret = (*f)(format, (arg)? &arg: NULL); else if (c == 'x' || c == 'X') ret = (*f)(format, atol(arg)); else if (c == 'd' || c == 'i' || c == 'u') ret = (*f)(format, atoi(arg)); else ret = (*f)(format); return (ret); } int _sprintf(int (*f)(const char *restrict, ...), \ char *str, char *format, char *arg) { int ret; char c; int fd[3]; ret = 0; setbuf(stdout, NULL); pipe(fd); fd[2] = dup(STDOUT_FILENO); dup2(fd[1], STDOUT_FILENO); ret = _printf((*f), format, arg); dup2(fd[2], STDOUT_FILENO); fflush(stdout); close(fd[1]); while (read(fd[0], &c, 1) > 0) *str++ = c; *str = '\0'; close(fd[0]); return (ret); } int assert_printf(char *format, char *arg) { int ret; int ft_ret; char out[256]; char ft_out[256]; if (arg == NULL || strcmp(arg, "") == 0) arg = NULL; ret = _sprintf(printf, out, format, arg); printf("%d = printf(\"%s\", '%s')\n%s\n", ret, format, arg, out); ft_ret = _sprintf(ft_printf, ft_out, format, arg); printf("%d = ft_printf(\"%s\", '%s')\n%s\n\n", ft_ret, format, arg, ft_out); assert(ret == ft_ret); assert(strcmp(out, ft_out) == 0); return (!(ret == ft_ret)); } int main(int args, char *argv[]) { int ret; char *fmt; char *format; char *arg; ret = 0; argv++; if (--args < 1) return (127); fmt = *argv++; format = ft_fmtsplit(&fmt); while (format != NULL) { if (*format == '%' && *(format + 1) != '%' && --args) arg = *argv++; else arg = NULL; ret |= assert_printf(format, arg); free(format); format = ft_fmtsplit(&fmt); } return (ret); }