1 #define _MCW_MALLOC_HEADER_
2 #include "mrilib.h"
3
4 #ifndef DARWIN
5 # ifdef __FreeBSD__
6 # include <stdlib.h>
7 # else
8 # include <malloc.h>
9 # endif
10 #endif
11
12 #include <unistd.h>
13 #include <time.h>
14
15 int MRILIB_verb = 0 ;
16
17 /*--------------------------------------------------------------------*/
18
19 static int be_quiet = 0 ;
machdep_be_quiet(void)20 int machdep_be_quiet(void){ return be_quiet ; }
21
22 /*--------------------------------------------------------------------
23 Code to provide runtime fixups for various machines
24 (things that can't be fixed by declarations in machdep.h).
25 This should be called at the start of every program.
26 ----------------------------------------------------------------------*/
27
machdep()28 void machdep()
29 {
30 long seed ;
31 static int first=1 ;
32
33 if( !first ) return ; else first = 0 ;
34
35 /*-- force use of mcw_malloc.c functions - 05 Nov 2001 --*/
36
37 #ifdef USING_MCW_MALLOC
38 if( AFNI_yesenv("AFNI_FORCE_MCW_MALLOC") ) enable_mcw_malloc();
39 #endif
40
41 /*-- disable mmap() in malloc() [21 Aug 2002: mostly] --*/
42
43 #if defined(LINUX) && defined(M_MMAP_MAX)
44 mallopt( M_MMAP_MAX , 1 ) ;
45 #endif
46
47 seed = (long)AFNI_numenv("AFNI_RANDOM_SEEDVAL") ;
48 init_rand_seed(seed) ;
49
50 be_quiet = AFNI_yesenv("AFNI_QUIET_STARTUP") ; /* 08 Dec 2010 */
51
52 if( AFNI_yesenv("AFNI_USE_FGETS") ) afni_fgets_setskip(1) ; /* 21 Dec 2011 */
53
54 /* [11 Jul 2019] change the default prefix for sub-brick numeric labels? */
55
56 { unsigned char *eee = (unsigned char *)my_getenv("AFNI_INDEX_PREFIX") ;
57 if( eee != NULL && !isspace(*eee) && *eee > 32 && *eee < 126 )
58 EDIT_set_index_prefix(*eee) ;
59 }
60
61 AFNI_do_nothing() ; /* 02 Oct 2012 */
62 return ;
63 }
64
65 /*-------------------------------------------------------------------*/
66
67 #include <unistd.h>
68 #ifdef USE_SYSCTL
69 # include <sys/types.h>
70 # include <sys/sysctl.h>
71 #endif
72
AFNI_get_ncpu(void)73 int AFNI_get_ncpu(void) /* 11 Feb 2016 */
74 {
75 int32_t nnn=0 ;
76
77 #ifdef _SC_NPROCESSORS_CONF
78 nnn = sysconf(_SC_NPROCESSORS_CONF) ;
79 #endif
80
81 #ifdef USE_SYSCTL
82 { size_t isiz=sizeof(int32_t) ;
83 if( nnn < 1 )
84 sysctlbyname( "hw.logicalcpu" , &nnn , &isiz , NULL,0 ) ;
85
86 if( nnn < 1 )
87 sysctlbyname( "hw.ncpu" , &nnn , &isiz , NULL,0 ) ;
88 }
89 #endif
90
91 if( nnn < 1 ) nnn = 1 ;
92
93 return (int)nnn ;
94 }
95
96 /*-------------------------------------------------------------------*/
97
AFNI_get_memsize(void)98 int64_t AFNI_get_memsize(void) /* in bytes -- 02 Aug 2016 */
99 {
100 int64_t mmm=0 , psiz=0 , pnum=0 ;
101
102 #ifdef _SC_PAGESIZE
103 psiz = (int64_t)sysconf(_SC_PAGESIZE) ;
104 #endif
105 #ifdef _SC_PHYS_PAGES
106 pnum = (int64_t)sysconf(_SC_PHYS_PAGES) ;
107 #endif
108 #ifdef _SC_AVPHYS_PAGES
109 if( pnum == 0 )
110 pnum = (int64_t)sysconf(_SC_AVPHYS_PAGES) ;
111 #endif
112 if( psiz > 0 && pnum > 0 ) return (psiz*pnum) ;
113
114 #ifdef USE_SYSCTL
115 { size_t isiz=sizeof(int64_t) ;
116 sysctlbyname( "hw.memsize" , &mmm , &isiz , NULL,0 ) ;
117 }
118 #endif
119 return mmm ;
120 }
121
122 /*-------------------------------------------------------------------*/
123
GetAfniWebBrowser(void)124 char * GetAfniWebBrowser(void)
125 {
126 static char *awb=NULL;
127
128 if( awb != NULL ) return(awb) ;
129
130 awb = my_getenv("AFNI_WEB_BROWSER") ;
131 #ifdef DARWIN
132 if( awb == NULL ) awb = "open" ; /* for Mac OS X */
133 #endif
134 if( awb == NULL ) awb = THD_find_executable( "firefox" ) ;
135 if( awb == NULL ) awb = THD_find_executable( "mozilla" ) ;
136 if( awb == NULL ) awb = THD_find_executable( "chrome" ) ;
137 if( awb == NULL ) awb = THD_find_executable( "google-chrome" ) ;
138 if( awb == NULL ) awb = THD_find_executable( "google-chrome-unstable" ) ;
139 if( awb == NULL ) awb = THD_find_executable( "netscape" ) ;
140 if( awb == NULL ) awb = THD_find_executable( "opera" ) ;
141 if( awb == NULL ) awb = THD_find_executable( "epiphany" ) ;
142 if( awb == NULL ) awb = THD_find_executable( "midori" ) ;
143 return(awb);
144 }
145
146 /*-------------------------------------------------------------------*/
147
GetAfniTextEditor(void)148 char * GetAfniTextEditor(void)
149 {
150 static char *ate=NULL;
151
152 if( ate != NULL ) return(ate) ;
153
154 ate = my_getenv("AFNI_GUI_EDITOR");
155 if( ate != NULL ) return(ate);
156
157 /* else, hunt */
158 if( ate == NULL ) ate = THD_find_executable( "nedit" ) ;
159 if( ate == NULL ) ate = THD_find_executable( "kedit" ) ;
160 if( ate == NULL ) ate = THD_find_executable( "gedit" ) ;
161 if( ate == NULL ) ate = THD_find_executable( "kwrite" ) ;
162 if( ate == NULL ) ate = THD_find_executable( "kate" ) ;
163 #ifdef DARWIN
164 if( ate == NULL ) ate = "open -t" ; /* for Mac OS X */
165 #endif
166
167 return(ate);
168 }
169
170 /*-------------------------------------------------------------------*/
171
GetAfniWebDownloader(void)172 char * GetAfniWebDownloader(void)
173 {
174 static char *ate=NULL;
175
176 if( ate != NULL ) return(ate) ;
177
178 ate = my_getenv("AFNI_WEB_DOWNLOADER");
179 if( ate != NULL ) return(ate);
180
181 /* else, hunt */
182 if( ate == NULL ) if (THD_find_executable( "curl" )) ate = "curl -O -f" ;
183 if( ate == NULL ) ate = THD_find_executable( "wget" ) ;
184
185 return(ate);
186 }
187
188 /*-------------------------------------------------------------------*/
189
GetAfniPDFViewer(void)190 char * GetAfniPDFViewer(void)
191 {
192 static char *ate=NULL;
193 ate = my_getenv("AFNI_PDF_VIEWER");
194
195 if( ate ) return ate;
196
197 /* else, hunt */
198 if( ate == NULL ) ate = THD_find_executable( "Preview" ) ;
199 if( ate == NULL ) ate = THD_find_executable( "evince" ) ;
200 if( ate == NULL ) ate = THD_find_executable( "acroread" ) ;
201 if( ate == NULL ) ate = GetAfniWebBrowser() ; /* last resort? */
202
203 return(ate);
204 }
205
206 /*-------------------------------------------------------------------*/
207
GetAfniImageViewer(void)208 char * GetAfniImageViewer(void)
209 {
210 static char *ate=NULL;
211 ate = my_getenv("AFNI_IMAGE_VIEWER");
212
213 if( ate ) return ate;
214
215 /* else, hunt */
216 if( ate == NULL ) ate = THD_find_executable( "Preview" ) ;
217 if( ate == NULL ) ate = THD_find_executable( "aiv" ) ;
218
219 return(ate);
220 }
221
222 /*-------------------------------------------------------------------*/
223
init_rand_seed(long int seed)224 void init_rand_seed( long int seed )
225 {
226 static int first=1 ;
227 if( ! first ) return ;
228 if( seed == 0 ){
229 FILE *ufp=fopen("/dev/urandom","rb") ;
230 seed = (long)time(NULL)+37*(long)getpid() ;
231 if( ufp != NULL ){ /* get some extra randomness [20 Nov 2016] */
232 byte urr=0 ;
233 (void)fread( &urr , sizeof(byte),1, ufp ); fclose(ufp);
234 seed += (long)urr ;
235 }
236 }
237 srand48(seed) ; first = 0 ; return ;
238 }
239
240 /*-------------------------------------------------------------------
241 To use the random()/srandom() library instead of srand48, do
242 #define USE_RANDOM
243 in machdep.h for your machine -- RWCox - 04 Sep 2001
244 ---------------------------------------------------------------------*/
245 #ifdef USE_RANDOM
srand48(long int s)246 void srand48( long int s ){ srandom((unsigned int)s); }
247
drand48(void)248 double drand48(void){ return (((double)random())/LONG_MAX); }
249
lrand48(void)250 long int lrand48(void){ return random(); }
251
mrand48(void)252 long int mrand48(void) /* need 32 bits but random only gives 31 */
253 { register long i , j , k ;
254 i = random() ; j = random() ;
255 k = ((i & 0xFFFF)<<16) | (j & 0xFFFF) ; return k ;
256 }
257 #endif /* USE_RANDOM */
258
259 /*-------------------------------------------------------------------
260 If the system doesn't provide this function for some reason ...
261 ---------------------------------------------------------------------*/
262
263 #ifdef NEED_XSETLOCALE
264 #include <locale.h>
_Xsetlocale(int category,const char * locale)265 char * _Xsetlocale( int category, const char * locale)
266 { return setlocale(category,locale) ; }
267 #endif
268
269 /*----- 09 Apr 2002 -----*/
270
271 #ifdef NEED_NL_LANGINFO
nl_langinfo()272 char * nl_langinfo(){ return "ISO-8859-1"; }
273 #endif
274
275 #ifdef NO_GAMMA
276 /*-------------------------------------------------------------------*/
277 /* If the system doesn't provide lgamma() for some reason.
278 ---------------------------------------------------------------------*/
279
280 /** log of gamma, for argument between 1 and 2 **/
281
gamma_12(double y)282 static double gamma_12( double y )
283 {
284 double x , g ;
285 x = y - 1.0 ;
286 g = ((((((( 0.035868343 * x - 0.193527818 ) * x
287 + 0.482199394 ) * x
288 - 0.756704078 ) * x
289 + 0.918206857 ) * x
290 - 0.897056937 ) * x
291 + 0.988205891 ) * x
292 - 0.577191652 ) * x + 1.0 ;
293 return log(g) ;
294 }
295
296 /** asymptotic expansion of ln(gamma(x)) for large positive x **/
297
298 #define LNSQRT2PI 0.918938533204672 /* ln(sqrt(2*PI)) */
299
gamma_asympt(double x)300 static double gamma_asympt(double x)
301 {
302 double sum ;
303
304 sum = (x-0.5)*log(x) - x + LNSQRT2PI + 1.0/(12.0*x) - 1./(360.0*x*x*x) ;
305 return sum ;
306 }
307 /** log of gamma, argument positive (not very efficient!) **/
308
lgamma(double x)309 double lgamma( double x )
310 {
311 double w , g ;
312
313 if( x <= 0.0 ){
314 fprintf(stderr,"Internal gamma: argument %g <= 0\a\n",x) ;
315 return 0.0 ;
316 }
317
318 if( x < 1.0 ) return gamma_12( x+1.0 ) - log(x) ;
319 if( x <= 2.0 ) return gamma_12( x ) ;
320 if( x >= 6.0 ) return gamma_asympt(x) ;
321
322 g = 0 ; w = x ;
323 while( w > 2.0 ){
324 w -= 1.0 ; g += log(w) ;
325 }
326 return ( gamma_12(w) + g ) ;
327 }
328 #endif /* NO_GAMMA */
329
330 /*---------------------------------------------------------------------------*/
331
Random_Insult(void)332 char * Random_Insult(void)
333 {
334 #define NINSULT 18
335 static char *ins[NINSULT]={ "Stupid" , "Moronic" , "Cretinous" ,
336 "Idiotic" , "Bozonic" , "Criminal" ,
337 "Repulsive" , "Dumb" , "Pinheaded" ,
338 "Fatuous" , "Asinine" , "Imbecilic" ,
339 "Oafish" , "Doltish" , "Duncical" ,
340 "Witless" , "Brainless" , "Flatbrained"
341 } ;
342 int ii = (lrand48()>>5) % NINSULT ;
343 return ins[ii] ;
344 }
345
346 /*---------------------------------------------------------------------------*/
347 #define SOL_TO_LOWER(c) ( ((c) >= 'A' && (c) <= 'Z') ? (c + 'a' - 'A') : (c) )
348
AFNI_strcasestr(const char * s1,const char * s2)349 char *AFNI_strcasestr(const char *s1, const char *s2)
350 {
351 char *s1u=NULL;
352 char *s2u=NULL;
353 char *so=NULL;
354 int off=0;
355 int i = 0;
356
357 if (!s1 || !s2 || s2[0] == '\0')
358 return(strstr(s1,s2)); /* let it fail as in strstr
359 You will get death if s2 is NULL */
360
361 if (!(s1u = strdup(s1))) {
362 fprintf(stderr,"AFNI_strcasestr: Failed to dup string 1\n");
363 return(NULL);
364 }
365 if (!(s2u = strdup(s2))) {
366 fprintf(stderr,"AFNI_strcasestr: Failed to dup string 2\n");
367 free(s1u);
368 return(NULL);
369 }
370 i=0; while (s1u[i]!='\0') { s1u[i] = SOL_TO_LOWER(s1u[i]); ++i; }
371 i=0; while (s2u[i]!='\0') { s2u[i] = SOL_TO_LOWER(s2u[i]); ++i; }
372
373 so = strstr(s1u,s2u);
374 off=0;
375 if (so) off = so-s1u;
376 free(s1u); free(s2u);
377
378 if (so) return((char*)s1+off);
379 return(NULL);
380 }
381
382 /*---------------------------------------------------------------------------*/
383
AFNI_do_nothing(void)384 void AFNI_do_nothing(void){
385 static int fdn=-666 ;
386 if( fdn == -666 ) fdn = open("/dev/null",O_WRONLY) ;
387 if( fdn >= 0 ) write(fdn," ",1) ;
388 return ;
389 }
390
391 /*---------------------------------------------------------------------------*/
392 /* Stuff for changing floating point rounding mode [25 Feb 2020] */
393
394 #ifdef USE_FENV
395 #include <fenv.h>
396 #pragma STDC FENV_ACCESS ON
397
398 static int fval[4] = { FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO };
399 static char *fstr[4] = { "nearst" , "upward" , "dnward" , "tozero" };
400
401 /* code to give a random value from 0..3, using compiled-in random numbers */
402
403 #ifdef USE_RANDOM /* man random */
404
405 # define ROUNVAL ((random() >> 3) % 4)
406 # define ROUNSEED(s) srandom((unsigned int)(s))
407
408 #else /* man nrand48 */
409
410 static unsigned short xran[3] = { 32100 , 42731 , 23172 } ; /* seed */
411 # undef SET_XRAN
412 # define SET_XRAN(xr,rss) \
413 ( (xr)[0]=((rss)>>16), (xr)[1]=((rss)&65535), (xr)[2]=(xr)[0]+(xr)[1]+17 )
414
415 # define ROUNVAL ((nrand48(xran) >> 3) % 4)
416 # define ROUNSEED(s) SET_XRAN(xran,(s))
417
418 #endif
419
420 /*--------- change the rounding randomly? --------*/
421
change_rounding_random(void)422 void change_rounding_random(void)
423 {
424 static int first=1 ; static int doit=0 ;
425
426 /*- setup stuff, first time only -*/
427
428 if( first ){
429 char *eee = my_getenv("AFNI_RANDOMIZE_ROUNDING") ;
430 doit = ( eee != NULL && (*eee=='Y' || *eee=='y') ) ; /* do this? */
431 if( doit ){ /* OK, setup randomization */
432 long seed=0 ;
433 eee = my_getenv("AFNI_RANDOMIZE_ROUNDING_SEED") ;
434 if( eee != NULL && isdigit(*eee) ) seed = (long)strtod(eee,NULL) ;
435 if( seed == 0 ) seed = (long)time(NULL)+37*(long)getpid() ;
436 ROUNSEED(seed) ;
437 fprintf(stderr,"++ AFNI_RANDOMIZE_ROUNDING seed = %d\n",(int)seed) ;
438 }
439 first = 0 ; /* never run this code again! */
440 }
441
442 if( doit ){ fesetround(fval[ROUNVAL]) ; }
443 return ;
444 }
445
446 /*-------- change the rounding as ordered by the pitiful user --------*/
447
change_rounding(int lll)448 void change_rounding(int lll)
449 {
450 if( lll >=0 && lll <= 3 ) fesetround( fval[lll] ) ;
451 return ;
452 }
453 #endif
454