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