Files
ft_printf/main.c
2022-04-29 15:18:54 +02:00

162 lines
3.6 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* main.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: gbaconni@student.42lausanne.ch +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/04/13 06:58:46 by gbaconni #+# #+# */
/* Updated: 2022/04/29 15:14:41 by gbaconni ### ########.fr */
/* */
/* ************************************************************************** */
#include <stdio.h> // printf
#include <string.h> // strlen
#include <ctype.h> // isdigit
#include <assert.h> // assert
#include "libftprintf/libftprintf.h"
int ft_skipchars(const char *s, char *chars)
{
int ret;
int i;
int hits;
ret = 0;
while (*s != '\0')
{
i = 0;
hits = 0;
while (chars[i] != '\0')
hits += (chars[i++] == *s);
if (hits > 0)
ret++;
else
break ;
s++;
}
return (ret);
}
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);
}