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