test: Allow skipping tests
[libisds.git] / test / test.c
blob00e2ddb231f164652dd90f42857f928bd40a80e7
1 #define _XOPEN_SOURCE 500
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <stdint.h>
5 #include <inttypes.h>
6 #include <stdarg.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <fcntl.h>
11 #ifndef _WIN32
12 #include <sys/mman.h>
13 #endif
15 #include <errno.h>
16 #include <string.h>
17 #include <unistd.h>
19 /* Global variables for each test unit */
20 char *reason = NULL;
21 void (*test_destructor_function)(void *) = NULL;
23 /* Print formated string into automtically reallocated @uffer.
24 * @buffer automatically reallocated buffer. Must be &NULL or preallocated
25 * memory.
26 * @format format string as for printf(3)
27 * @ap list of variadic arguments, after call will be in udefined state
28 * @Returns number of bytes printed. In case of errror, -1 and NULL @buffer */
29 int test_vasprintf(char **buffer, const char *format, va_list ap) {
30 va_list aq;
31 int length, new_length;
32 char *new_buffer;
34 if (!buffer || !format) {
35 if (buffer) {
36 free(*buffer);
37 *buffer = NULL;
39 return -1;
42 va_copy(aq, ap);
43 length = vsnprintf(NULL, 0, format, aq) + 1;
44 va_end(aq);
45 if (length <= 0) {
46 free(*buffer);
47 *buffer = NULL;
48 return -1;
51 new_buffer = realloc(*buffer, length);
52 if (!new_buffer) {
53 free(*buffer);
54 *buffer = NULL;
55 return -1;
57 *buffer = new_buffer;
59 new_length = vsnprintf(*buffer, length, format, ap);
60 if (new_length >= length) {
61 free(*buffer);
62 *buffer = NULL;
63 return -1;
66 return new_length;
70 /* Print formated string into automtically reallocated @uffer.
71 * @buffer automatically reallocated buffer. Must be &NULL or preallocated
72 * memory.
73 * @format format string as for printf(3)
74 * @... variadic arguments
75 * @Returns number of bytes printed. In case of errror, -1 and NULL @buffer */
76 int test_asprintf(char **buffer, const char *format, ...) {
77 int ret;
78 va_list ap;
79 va_start(ap, format);
80 ret = test_vasprintf(buffer, format, ap);
81 va_end(ap);
82 return ret;
86 #ifdef _WIN32
87 int test_mmap_file(const char *file, int *fd, void **buffer, size_t *length) {
88 struct stat file_info;
89 int ret, pos = 0;
91 if (!file || !fd || !buffer || !length) return -1;
93 *fd = open(file, O_RDONLY);
94 if (*fd == -1) {
95 fprintf(stderr, "%s: Could not open file: %s\n", file, strerror(errno));
96 return -1;
99 if (-1 == fstat(*fd, &file_info)) {
100 fprintf(stderr, "%s: Could not get file size: %s\n", file,
101 strerror(errno));
102 close(*fd);
103 return -1;
105 if (file_info.st_size < 0) {
106 fprintf(stderr, "File `%s' has negative size: %" PRIdMAX "\n", file,
107 (intmax_t) file_info.st_size);
108 close(*fd);
109 return -1;
111 *length = file_info.st_size;
112 *buffer = malloc(*length);
114 if (!*buffer) {
115 fprintf(stderr, "%s: Could not allocate memory for file mapping: %s\n",
116 file, strerror(errno));
117 close(*fd);
118 return -1;
121 do {
122 ret = read(*fd, *buffer + pos, *length - pos);
124 if (ret > 0) {
125 pos += ret;
127 } while ((ret < 0 && errno == EINTR) || (ret > 0 && pos < *length));
129 if (ret < 0) {
130 fprintf(stderr, "%s: Could not map file to memory: %s\n", file,
131 strerror(errno));
132 free(*buffer);
133 *buffer = NULL;
134 close(*fd);
135 return -1;
138 return 0;
141 int test_munmap_file(int fd, void *buffer, size_t length) {
142 int err = 0;
143 free(buffer);
145 err = close(fd);
146 if (err) {
147 fprintf(stderr, "Could close file descriptor %d: %s\n", fd,
148 strerror(errno));
151 return err;
153 #else
154 int test_mmap_file(const char *file, int *fd, void **buffer, size_t *length) {
155 struct stat file_info;
157 if (!file || !fd || !buffer || !length) return -1;
160 *fd = open(file, O_RDONLY);
161 if (*fd == -1) {
162 fprintf(stderr, "%s: Could not open file: %s\n", file, strerror(errno));
163 return -1;
166 if (-1 == fstat(*fd, &file_info)) {
167 fprintf(stderr, "%s: Could not get file size: %s\n", file,
168 strerror(errno));
169 close(*fd);
170 return -1;
172 if (file_info.st_size < 0) {
173 fprintf(stderr, "File `%s' has negative size: %" PRIdMAX "\n", file,
174 (intmax_t) file_info.st_size);
175 close(*fd);
176 return -1;
178 *length = file_info.st_size;
180 *buffer = mmap(NULL, *length, PROT_READ, MAP_PRIVATE, *fd, 0);
181 if (*buffer == MAP_FAILED) {
182 fprintf(stderr, "%s: Could not map file to memory: %s\n", file,
183 strerror(errno));
184 close(*fd);
185 return -1;
188 return 0;
192 int test_munmap_file(int fd, void *buffer, size_t length) {
193 int err = 0;
194 long int page_size = sysconf(_SC_PAGE_SIZE);
195 size_t pages = (length % page_size) ?
196 ((length / page_size) + 1) * page_size:
197 length;
199 err = munmap(buffer, pages);
200 if (err) {
201 fprintf(stderr, "Could not unmap memory at %p and length %zu: %s\n",
202 buffer, pages, strerror(errno));
205 err = close(fd);
206 if (err) {
207 fprintf(stderr, "Could close file descriptor %d: %s\n", fd,
208 strerror(errno));
211 return err;
213 #endif