1 /************************************************************************
2 ************************************************************************
3 FAUST compiler
4 Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
5 ---------------------------------------------------------------------
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ************************************************************************
20 ************************************************************************/
21
22 #include <stdint.h>
23 #include <stdlib.h>
24 #include <string>
25
26 #include "compatibility.hh"
27 #include "math.h"
28
29 #if defined(__MINGW32__) || defined(_WIN32)
30 // Simulate some Unix fonctions on Windows
31 #include <time.h>
32
33 #if !defined(INT) & !defined(FLOAT)
34 #include <windows.h>
35 //#include <Winsock2.h>
36 #else
37 #include <io.h>
38 #endif
39
40 #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
41 #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
42 #else
43 #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
44 #endif
45
gettimeofday(struct timeval * tv,struct timezone * tz)46 int gettimeofday(struct timeval* tv, struct timezone* tz)
47 {
48 FILETIME ft;
49 uint64_t tmpres = 0;
50 static int tzflag;
51
52 if (NULL != tv) {
53 GetSystemTimeAsFileTime(&ft);
54
55 tmpres |= ft.dwHighDateTime;
56 tmpres <<= 32;
57 tmpres |= ft.dwLowDateTime;
58
59 /*converting file time to unix epoch*/
60 tmpres -= DELTA_EPOCH_IN_MICROSECS;
61 tmpres /= 10; /*convert into microseconds*/
62 tv->tv_sec = (long)(tmpres / 1000000UL);
63 tv->tv_usec = (long)(tmpres % 1000000UL);
64 }
65
66 if (NULL != tz) {
67 if (!tzflag) {
68 _tzset();
69 tzflag++;
70 }
71 tz->tz_minuteswest = _timezone / 60;
72 tz->tz_dsttime = _daylight;
73 }
74 return 0;
75 }
isatty(int file)76 int isatty(int file)
77 {
78 return 0;
79 }
80
81 #if defined(_MBCS) || __MINGW32__
chdir(const char * path)82 int chdir(const char* path)
83 {
84 return !SetCurrentDirectory(path);
85 }
86
mkdir(const char * path,unsigned int attribute)87 int mkdir(const char* path, unsigned int attribute)
88 {
89 if (CreateDirectory(path, NULL) == 0) {
90 // mkdir has to be successfull in case the path already exists
91 if (GetLastError() == ERROR_ALREADY_EXISTS) {
92 return 0;
93 } else {
94 return -1;
95 }
96 } else {
97 return 0;
98 }
99 }
100
getcwd(char * str,int size)101 char* getcwd(char* str, int size)
102 {
103 GetCurrentDirectory(size, str);
104 return str;
105 }
getFaustPathname(char * str,unsigned int size)106 void getFaustPathname(char* str, unsigned int size)
107 {
108 GetModuleFileName(NULL, str, size);
109 }
110 #else
chdir(const char * path)111 bool chdir(const char* path)
112 {
113 wchar_t wstr[2048];
114 mbstowcs(wstr, path, 2048);
115 return !SetCurrentDirectory(wstr);
116 }
117
mkdir(const char * path,unsigned int attribute)118 int mkdir(const char* path, unsigned int attribute)
119 {
120 wchar_t wstr[2048];
121 mbstowcs(wstr, path, 2048);
122 return CreateDirectory(wstr, NULL);
123 }
124
getcwd(char * str,unsigned int size)125 char* getcwd(char* str, unsigned int size)
126 {
127 wchar_t wstr[2048];
128 GetCurrentDirectory(2048, wstr);
129 wcstombs(str, wstr, size);
130 return str;
131 }
132
getFaustPathname(char * str,unsigned int size)133 void getFaustPathname(char* str, unsigned int size)
134 {
135 wchar_t wstr[2048];
136 GetModuleFileName(NULL, wstr, 2048);
137 wcstombs(str, wstr, size);
138 }
139
140 #endif
141
142 typedef union {
143 double value;
144 struct {
145 unsigned int lsw;
146 unsigned int msw;
147 } parts;
148 } ieee_double_shape_type;
149
150 #define EXTRACT_WORDS(ix0, ix1, d) \
151 do { \
152 ieee_double_shape_type ew_u; \
153 ew_u.value = (d); \
154 (ix0) = ew_u.parts.msw; \
155 (ix1) = ew_u.parts.lsw; \
156 } while (0)
157
158 /* Get the more significant 32 bit int from a double. */
159
160 #define GET_HIGH_WORD(i, d) \
161 do { \
162 ieee_double_shape_type gh_u; \
163 gh_u.value = (d); \
164 (i) = gh_u.parts.msw; \
165 } while (0)
166
167 /* Get the less significant 32 bit int from a double. */
168
169 #define GET_LOW_WORD(i, d) \
170 do { \
171 ieee_double_shape_type gl_u; \
172 gl_u.value = (d); \
173 (i) = gl_u.parts.lsw; \
174 } while (0)
175
176 #define SET_HIGH_WORD(d, v) \
177 do { \
178 ieee_double_shape_type sh_u; \
179 sh_u.value = (d); \
180 sh_u.parts.msw = (v); \
181 (d) = sh_u.value; \
182 } while (0)
183
184 #if !defined(__MINGW32__) && (_MSC_VER <= 1700)
rint(double nr)185 double rint(double nr)
186 {
187 double f = floor(nr);
188 double c = ceil(nr);
189 return (((c - nr) >= (nr - f)) ? f : c);
190 }
191 #endif
192
realpath(const char * path,char resolved_path[MAX_PATH])193 char* realpath(const char* path, char resolved_path[MAX_PATH])
194 {
195 if (GetFullPathNameA(path, MAX_PATH, resolved_path, 0)) {
196 return resolved_path;
197 } else {
198 return "";
199 }
200 }
201
basename(const char * fullpath)202 char* basename(const char* fullpath)
203 {
204 char drive[_MAX_DRIVE];
205 char dir[_MAX_DIR];
206 char fname[_MAX_FNAME];
207 char ext[_MAX_EXT];
208
209 _splitpath(fullpath, drive, dir, fname, ext);
210
211 std::string fullname = fullpath;
212 size_t pos = fullname.rfind(fname);
213
214 return (char*)&fullpath[pos];
215 }
216
217 #if (_MSC_VER <= 1700)
remainder(double x,double p)218 double remainder(double x, double p)
219 {
220 int hx, hp;
221 unsigned int sx, lx, lp;
222 double p_half;
223
224 EXTRACT_WORDS(hx, lx, x);
225 EXTRACT_WORDS(hp, lp, p);
226 sx = hx & 0x80000000;
227 hp &= 0x7fffffff;
228 hx &= 0x7fffffff;
229
230 /* purge off exception values */
231 if ((hp | lp) == 0) return (x * p) / (x * p); /* p = 0 */
232 if ((hx >= 0x7ff00000) || /* x not finite */
233 ((hp >= 0x7ff00000) && /* p is NaN */
234 (((hp - 0x7ff00000) | lp) != 0)))
235 return (x * p) / (x * p);
236
237 static const double zero = 0.0;
238 if (hp <= 0x7fdfffff) x = fmod(x, p + p); /* now x < 2p */
239 if (((hx - hp) | (lx - lp)) == 0) return zero * x;
240 x = fabs(x);
241 p = fabs(p);
242 if (hp < 0x00200000) {
243 if (x + x > p) {
244 x -= p;
245 if (x + x >= p) x -= p;
246 }
247 } else {
248 p_half = 0.5 * p;
249 if (x > p_half) {
250 x -= p;
251 if (x >= p_half) x -= p;
252 }
253 }
254 GET_HIGH_WORD(hx, x);
255 SET_HIGH_WORD(x, hx ^ sx);
256 return x;
257 }
258 #endif
259
260 #else // Linux
261
262 #include <stdlib.h>
263 #include <string.h>
264 #include <limits.h>
getFaustPathname(char * str,unsigned int size)265 void getFaustPathname(char* str, unsigned int size)
266 {
267 char buff[PATH_MAX];
268 ssize_t len = ::readlink("/proc/self/exe", buff, sizeof(buff)-1);
269 if (len != -1) {
270 buff[len] = '\0';
271 strncpy(str, buff, len);
272 } else {
273 char* path = getenv("_");
274 if (path) {
275 strncpy(str, path, size);
276 } else {
277 // prevent the case of _ undefined
278 strncpy(str, "/usr/local/bin/faust", size);
279 }
280 }
281 }
282
283 #endif
284