/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* main.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: baco +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/04/13 06:58:46 by gbaconni #+# #+# */ /* Updated: 2022/04/18 09:12:07 by gbaconni ### lausanne.ch */ /* */ /* ************************************************************************** */ #include // printf #include // va_list, va_start, va_end #include // write #include // strlen #include // malloc, free #include // isdigit #include // assert #include #include #include #include #include // wait #include "libftprintf/libftprintf.h" void ft_begin(int *fd) { pipe(fd); fd[2] = dup(STDOUT_FILENO); dup2(fd[1], STDOUT_FILENO); } void ft_end(int *fd, char *str) { char c; dup2(fd[2], STDOUT_FILENO); fflush(stdout); close(fd[1]); while (read(fd[0], &c, 1) > 0) *str++ = c; *str = '\0'; close(fd[0]); } void ft_begin2(char *out) { freopen("/dev/null", "a", stdout); setbuf(stdout, out); } void ft_end2(void) { freopen("/dev/tty", "a", stdout); } int ft_sprintf(char *str, const char *format, ...) { va_list ap; int ret; int state; char c; pid_t cpid; int pipefd[3]; const int piperead = 0; const int pipewrite = 1; const int pipestdout = 2; ret = 0; pipe(pipefd); cpid = fork(); if (cpid == 0) { close(pipefd[piperead]); pipefd[pipestdout] = dup(STDOUT_FILENO); dup2(pipefd[pipewrite], STDOUT_FILENO); va_start(ap, format); ret = ft_vprintf(format, ap); va_end(ap); fflush(stdout); dup2(pipefd[pipestdout], STDOUT_FILENO); close(pipefd[pipestdout]); close(pipefd[pipewrite]); exit (ret); } else { close(pipefd[pipewrite]); while (read(pipefd[piperead], &c, 1) > 0) *str++ = c; close(pipefd[piperead]); wait(&state); return (WEXITSTATUS(state)); } } size_t ft_unescape_len(const char *str) { size_t len; len = 0; while (*str != '\0') { if (*str == '\\') str++; len++; str++; } return (len); } char ft_unescape_char(const char c) { if (c == 'a') return ('\a'); else if (c == 'b') return ('\b'); else if (c == 't') return ('\t'); else if (c == 'n') return ('\n'); else if (c == 'v') return ('\v'); else if (c == 'f') return ('\f'); else if (c == 'r') return ('\r'); else if (c == 'e') return ('\033'); else return (c); } char *ft_unescape(const char *str) { char *s; void *ptr; s = (char *) ft_calloc(ft_unescape_len(str) + 1, sizeof(char)); if (s == NULL) return (NULL); ptr = s; while (*str != '\0') { if (*str == '\\') *s++ = ft_unescape_char(*++str); else *s++ = *str; str++; } *s = '\0'; s = ptr; return (s); } int main(int argc, char *argv[]) { int ft_ret; int ret; char out[256]; char ft_out[256]; char *format; char *f; int d; char c; char *s; int x; void *ptr; int fd[3]; d = 0; c = '\0'; s = ""; x = 42; ptr = &x; (void)s; if (argc > 1) { f = argv[1]; format = ft_unescape(f); if (format[0] == '%') { if (format[1] == 'c') { c = argv[2][0]; ret = sprintf(out, format, c); printf("%d = printf(\"%s\", '%c')\n%s\n", ret, f, c, out); ft_begin(fd); ft_ret = ft_printf(format, c); ft_end(fd, ft_out); printf("%d = ft_printf(\"%s\", '%c')\n%s\n\n", ft_ret, f, c, ft_out); assert(ret == ft_ret); assert(strcmp(out, ft_out) == 0); } else if (format[1] == 's') { s = argv[2]; ret = sprintf(out, format, s); printf("%d = printf(\"%s\", \"%s\")\n%s\n", ret, f, s, out); ft_begin(fd); ft_ret = ft_printf(format, s); ft_end(fd, ft_out); printf("%d = ft_printf(\"%s\", \"%s\")\n%s\n\n", ft_ret, f, s, ft_out); assert(ret == ft_ret); assert(strcmp(out, ft_out) == 0); } else if (format[1] == 'p') { s = argv[2]; if (ft_strlen(s) == 0) { s = NULL; ptr = NULL; } ret = sprintf(out, format, ptr); printf("%d = printf(\"%s\", %p)\n%s\n", ret, f, ptr, out); ft_begin(fd); ft_ret = ft_printf(format, ptr); ft_end(fd, ft_out); printf("%d = ft_printf(\"%s\", %p)\n%s\n\n", ft_ret, f, ptr, ft_out); assert(ret == ft_ret); assert(strcmp(out, ft_out) == 0); } else if (format[1] == 'd' || format[1] == 'i' || format[1] == 'u') { d = atoi(argv[2]); ret = sprintf(out, format, d); printf("%d = printf(\"%s\", %d)\n%s\n", ret, f, d, out); ft_begin(fd); ft_ret = ft_printf(format, d); ft_end(fd, ft_out); printf("%d = ft_printf(\"%s\", %d)\n%s\n\n", ft_ret, f, d, ft_out); assert(ret == ft_ret); assert(strcmp(out, ft_out) == 0); } else if (format[1] == 'x' || format[1] == 'X') { d = atoi(argv[2]); ret = sprintf(out, format, d); printf("%d = printf(\"%s\", %d)\n%s\n", ret, f, d, out); ft_begin(fd); ft_ret = ft_printf(format, d); ft_end(fd, ft_out); printf("%d = ft_printf(\"%s\", %d)\n%s\n\n", ft_ret, f, d, ft_out); assert(ret == ft_ret); assert(strcmp(out, ft_out) == 0); } } else { s = argv[2]; ret = sprintf(out, format, s); printf("%d = printf(\"%s\", \"%s\")\n%s\n", ret, f, s, out); ft_begin(fd); ft_ret = ft_printf(format, s); ft_end(fd, ft_out); printf("%d = ft_printf(\"%s\", \"%s\")\n%s\n\n", ft_ret, f, s, ft_out); assert(ret == ft_ret); assert(strcmp(out, ft_out) == 0); } free(format); } return (0); }