-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathtest.c
138 lines (120 loc) · 4.11 KB
/
test.c
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/* test.c implements the main function for unit tests, so that it runs
* correctly under the automake testing functions
*
* written nml 2003-10-14
*
*/
#include "firstinclude.h"
#include "test.h"
#include "getlongopt.h"
#include "zglob.h"
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
/* internal function to open a file specified in the arguments */
static FILE *argfile(int argc, char **argv, FILE *output) {
FILE *fp;
struct getlongopt *parser; /* option parser */
int id; /* id of parsed option */
const char *arg; /* argument of parsed option */
enum getlongopt_ret ret; /* return value from option parser */
struct getlongopt_opt opts[] = {
{"input", '\0', GETLONGOPT_ARG_REQUIRED, 'i'}
};
if ((parser = getlongopt_new(argc - 1, (const char **) &argv[1], opts,
sizeof(opts) / sizeof(*opts)))) {
/* succeeded, do nothing */
} else {
fprintf(output, "failed to initialise options parser\n");
exit(EXIT_FAILURE);
}
while ((ret = getlongopt(parser, &id, &arg)) == GETLONGOPT_OK) {
switch (id) {
case 'i':
/* specified input */
if ((fp = fopen(arg, "rb"))) {
getlongopt_delete(parser);
return fp;
} else {
fprintf(output,
"unable to open file '%s': %s\n", arg, strerror(errno));
exit(EXIT_FAILURE);
}
default: assert(0);
}
}
getlongopt_delete(parser);
return NULL;
}
int main(int argc, char **argv) {
FILE *fp;
unsigned int i,
len,
files = 0,
ret = 1;
char *srcdir;
char buf[FILENAME_MAX + 1];
glob_t globbuf;
/* check for srcdir environmental variable which indicates that
* we're running in an automake test case, and that we should
* locate test files ourselves */
if ((srcdir = getenv("srcdir"))) {
/* glob files in directory to find ones we want to run over */
snprintf(buf, FILENAME_MAX, "%s/%s.*", srcdir, *argv);
globbuf.gl_offs = 1;
if (glob(buf, 0, NULL, &globbuf) != 0) {
perror("glob failed");
return EXIT_FAILURE;
}
len = strlen(srcdir) + 1 + strlen(*argv) + 1;
/* traverse the glob */
for (i = 0; i < globbuf.gl_pathc; i++) {
/* don't execute on .c and .o files */
if (strcmp(globbuf.gl_pathv[i] + len, "c")
&& strcmp(globbuf.gl_pathv[i] + len, "o")) {
if ((fp = fopen(globbuf.gl_pathv[i], "rb"))) {
files++;
if (!(ret = test_file(fp, argc, argv))) {
fprintf(stderr, "failed in globbed file %s\n",
globbuf.gl_pathv[i]);
/* don't bother cleaning up */
return EXIT_FAILURE;
}
fclose(fp);
} else {
fprintf(stderr, "couldn't open globbed file %s: %s\n",
globbuf.gl_pathv[i], strerror(errno));
/* don't bother cleaning up */
return EXIT_FAILURE;
}
}
}
globfree(&globbuf);
if (!files && !(ret = test_file(NULL, argc, argv))) {
fprintf(stderr, "testing with no file failed\n");
return EXIT_FAILURE;
}
/* use specified file if there is one */
} else if ((fp = argfile(argc, argv, stderr))) {
if (!(ret = test_file(fp, argc, argv))) {
fclose(fp);
fprintf(stderr, "specified file failed test\n");
return EXIT_FAILURE;
}
fclose(fp);
/* fallback to stdin */
} else {
if (!(ret = test_file(stdin, argc, argv))) {
fprintf(stderr, "stdin failed test\n");
return EXIT_FAILURE;
}
}
if (ret == EXIT_DOESNT_COUNT) {
return EXIT_DOESNT_COUNT;
} else {
return EXIT_SUCCESS;
}
}