[tests] add run_on_default_source helper
[aubio.git] / tests / utils_tests.h
1 #include <time.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <math.h>
5 #include <assert.h>
6 #include "config.h"
7
8 #ifdef HAVE_STRING_H
9 #include <string.h>
10 #endif
11
12 #ifdef HAVE_UNISTD_H
13 #include <unistd.h> // unlink, close
14 #endif
15
16 #ifdef HAVE_LIMITS_H
17 #include <limits.h> // PATH_MAX
18 #endif /* HAVE_LIMITS_H */
19 #ifndef PATH_MAX
20 #define PATH_MAX 1024
21 #endif
22
23 #ifndef AUBIO_TESTS_SOURCE
24 #error "AUBIO_TESTS_SOURCE is not defined"
25 #endif
26
27 #ifdef HAVE_C99_VARARGS_MACROS
28 #define PRINT_ERR(...)   fprintf(stderr, "AUBIO-TESTS ERROR: " __VA_ARGS__)
29 #define PRINT_MSG(...)   fprintf(stdout, __VA_ARGS__)
30 #define PRINT_DBG(...)   fprintf(stderr, __VA_ARGS__)
31 #define PRINT_WRN(...)   fprintf(stderr, "AUBIO-TESTS WARNING: " __VA_ARGS__)
32 #else
33 #define PRINT_ERR(format, args...)   fprintf(stderr, "AUBIO-TESTS ERROR: " format , ##args)
34 #define PRINT_MSG(format, args...)   fprintf(stdout, format , ##args)
35 #define PRINT_DBG(format, args...)   fprintf(stderr, format , ##args)
36 #define PRINT_WRN(format, args...)   fprintf(stderr, "AUBIO-TESTS WARNING: " format, ##args)
37 #endif
38
39 #ifndef M_PI
40 #define M_PI         (3.14159265358979323846)
41 #endif
42
43 #ifndef RAND_MAX
44 #define RAND_MAX 32767
45 #endif
46
47 // are we on windows ? or are we using -std=c99 ?
48 #if defined(HAVE_WIN_HACKS) || defined(__STRICT_ANSI__)
49 // http://en.wikipedia.org/wiki/Linear_congruential_generator
50 // no srandom/random on win32
51
52 uint_t srandom_seed = 1029;
53
54 void srandom(uint_t new_seed) {
55     srandom_seed = new_seed;
56 }
57
58 uint_t random(void) {
59     srandom_seed = 1664525 * srandom_seed + 1013904223;
60     return srandom_seed;
61 }
62 #endif
63
64 void utils_init_random (void);
65
66 void utils_init_random (void) {
67   time_t now = time(0);
68   struct tm *tm_struct = localtime(&now);
69   size_t **tm_address = (void*)&tm_struct;
70   int seed = tm_struct->tm_sec + (size_t)tm_address;
71   //PRINT_WRN("current seed: %d\n", seed);
72   srandom ((unsigned int)seed);
73 }
74
75 // create_temp_sink / close_temp_sink
76 #if defined(__GNUC__) // mkstemp
77
78 int check_source(char *source_path)
79 {
80   return access(source_path, R_OK);
81 }
82
83 int create_temp_sink(char *sink_path)
84 {
85   return mkstemp(sink_path);
86 }
87
88 int close_temp_sink(char *sink_path, int sink_fildes)
89 {
90   int err;
91   if ((err = close(sink_fildes)) != 0) return err;
92   if ((err = unlink(sink_path)) != 0) return err;
93   return err;
94 }
95
96 #elif defined(HAVE_WIN_HACKS) //&& !defined(__GNUC__)
97 // windows workaround, where mkstemp does not exist...
98
99 int check_source(char *source_path)
100 {
101   return _access(source_path, 04);
102 }
103
104 int create_temp_sink(char *templ)
105 {
106   int i = 0;
107   static const char letters[] = "abcdefg0123456789";
108   int letters_len = strlen(letters);
109   int templ_len = strlen(templ);
110   if (templ_len == 0) return 0;
111   utils_init_random();
112   for (i = 0; i < 6; i++)
113   {
114     templ[templ_len - i] = letters[rand() % letters_len];
115   }
116   return 1;
117 }
118
119 int close_temp_sink(char* sink_path, int sink_fildes) {
120   // the file should be closed when not using mkstemp, no need to open it
121   if (sink_fildes == 0) return 1;
122   return _unlink(sink_path);
123 }
124
125 #else // windows workaround
126 // otherwise, we don't really know what to do yet
127 #error "mkstemp undefined, but not on windows. additional workaround required."
128 #endif
129
130 // pass progname / default
131 int run_on_default_source( int main(int, char**) )
132 {
133   const int argc = 2;
134   int err = 0;
135   char** argv = (char**)calloc(argc, sizeof(char*));
136   argv[0] = __FILE__;
137   argv[1] = AUBIO_TESTS_SOURCE;
138   // check if the file can be read
139   if ( check_source(argv[1]) ) return 1;
140   err = main(argc, argv);
141   if (argv) free(argv);
142   return err;
143 }
144
145 int run_on_default_sink( int main(int, char**) )
146 {
147   const int argc = 2;
148   int err = 0;
149   char** argv = (char**)calloc(argc, sizeof(char*));
150   char sink_path[PATH_MAX] = "tmp_aubio_XXXXXX";
151   int fd = create_temp_sink(sink_path);
152   if (!fd) return 1;
153   argv[0] = __FILE__;
154   argv[1] = sink_path;
155   err = main(argc, argv);
156   close_temp_sink(sink_path, fd);
157   if (argv) free(argv);
158   return err;
159 }