aboutsummaryrefslogtreecommitdiff
path: root/header.h
blob: ddbc9fdfbc2d3870f694a18cd46f96861fbaa223 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   header.h                                           :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: cacharle <marvin@42.fr>                    +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2020/02/06 18:13:32 by cacharle          #+#    #+#             */
/*   Updated: 2020/02/21 01:21:48 by cacharle         ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#ifndef FT_PRINTF_TEST_HEADER_H
# define FT_PRINTF_TEST_HEADER_H

# include <sys/wait.h>
# include <stdlib.h>
# include <stdio.h>
# include <unistd.h>
# include <string.h>
# include <stdbool.h>

int pid;
bool signaled;
static bool origin_signaled = false;
static bool user_signaled = false;
int origin_ret;
int user_ret;
char *origin_buf;
char *user_buf;

void generated_test(void);
void saved_test(void);

int ft_printf(const char *format, ...);

void print_buf_ko(char *msg);
void print_ret_ko(char *msg);
void print_signaled_ko(char *msg);
void print_ok(void);
void print_ko(void);
void ft_putstr_non_printable(char *str);

void test_setup(void);
void test_tear_down(void);
char *read_stdout_buf(void);

# define TEST_SEGFAULT(x) do {       \
	if ((pid = fork()) < 0)          \
	exit(EXIT_FAILURE);              \
	if (pid == 0) {                  \
		do { x } while(0);           \
		exit(EXIT_SUCCESS);          \
	} else {                         \
		wait(&pid);                  \
		signaled = WIFSIGNALED(pid); \
	}                                \
} while(0);

# define TEST_PRINTF(...) do {              \
	test_setup();                           \
	TEST_SEGFAULT(                          \
		origin_ret = printf(__VA_ARGS__);   \
	);                                      \
	origin_buf = strdup(read_stdout_buf()); \
	origin_signaled = signaled;             \
	TEST_SEGFAULT(                          \
		user_ret = ft_printf(__VA_ARGS__);  \
	);                                      \
	user_buf = strdup(read_stdout_buf());   \
	user_signaled = signaled;               \
	test_tear_down();                       \
} while (0)

# define ASSERT_PRINTF(...) do {                   \
	TEST_PRINTF(__VA_ARGS__);                      \
	if (!origin_signaled && user_signaled)         \
		print_signaled_ko(#__VA_ARGS__);           \
	else if (origin_signaled && user_signaled)     \
		print_ok();                                \
	else if (!origin_signaled && !user_signaled) { \
		if (memcmp(origin_buf, user_buf,           \
			    strlen(origin_buf) + 1) != 0)      \
			print_buf_ko(#__VA_ARGS__);            \
		else if (origin_ret != user_ret)           \
			print_ret_ko(#__VA_ARGS__);            \
		else                                       \
		print_ok();                                \
	}                                              \
	if (!origin_signaled) free(origin_buf);        \
	if (!user_signaled) free(user_buf);            \
} while(0);

#endif