1 /*
2  * util-inl.h
3  *
4  *  Created on: Mar 28, 2014
5  *      Author: meiermark
6  */
7 
8 #ifndef UTIL_INL_H_
9 #define UTIL_INL_H_
10 
11 #include <cstdlib>
12 
13 //// max and min
dmax(double x,double y)14 inline double dmax(double x, double y) {
15   return (x > y ? x : y);
16 }
dmin(double x,double y)17 inline double dmin(double x, double y) {
18   return (x < y ? x : y);
19 }
imax(int x,int y)20 inline int imax(int x, int y) {
21   return (x > y ? x : y);
22 }
imin(int x,int y)23 inline int imin(int x, int y) {
24   return (x < y ? x : y);
25 }
iabs(int x)26 inline int iabs(int x) {
27   return (x >= 0 ? x : -x);
28 }
29 
30 // Rounding up, rounding down and rounding to nearest integer
iceil(double x)31 inline int iceil(double x) {
32   return int(ceil(x));
33 }
ifloor(double x)34 inline int ifloor(double x) {
35   return int(floor(x));
36 }
iround(double x)37 inline int iround(double x) {
38   return int(floor(x + 0.5));
39 }
40 
41 //// Generalized mean: d=0: sqrt(x*y)  d=1: (x+y)/2  d->-inf: min(x,y)  d->+inf: max(x,y)
fmean(double x,double y,double d)42 inline double fmean(double x, double y, double d) {
43   return pow((pow(x, d) + pow(y, d)) / 2, 1. / d);
44 }
45 
46 // log base 2
safe_log2(float x)47 inline float safe_log2(float x) {
48   return (x <= 0 ? (float) (-100000) : 1.442695041 * log(x));
49 }
safe_log10(float x)50 inline float safe_log10(float x) {
51   return (x <= 0 ? (float) (-100000) : 0.434294481 * log(x));
52 }
53 
54 /////////////////////////////////////////////////////////////////////////////////////
55 // fast log base 2
56 /////////////////////////////////////////////////////////////////////////////////////
57 
58 // Fast log2
59 // ATTENTION: need to compile with g++ -fno-strict-aliasing when using -O2 or -O3!!!
60 // Maximum deviation: +/- 2.1E-5
61 // Run time: ~1.2E-8s on Intel core2 2.13GHz, log2(): 5.4E-8s
62 // For a negative argument, -128 is returned.
63 // The function makes use of the representation of 4-byte floating point numbers:
64 // seee eeee emmm mmmm mmmm mmmm mmmm mmmm
65 // s is the sign, eee eee e gives the exponent + 127 (in hex: 0x7f).
66 // The following 23 bits give the mantisse, the binary digits after the decimal
67 // point:  x = (-1)^s * 1.mmmmmmmmmmmmmmmmmmmmmmm * 2^(eeeeeeee-127)
68 // Therefore,  log2(x) = eeeeeeee-127 + log2(1.mmmmmm...)
69 //                     = eeeeeeee-127 + log2(1+y),  where y = 0.mmmmmm...
70 //                     ~ eeeeeeee-127 + ((a*y+b)*y+c)*y
71 // The coefficients a, b  were determined by a least squares fit, and c=1-a-b to get 1 at y=1.
72 // Lower/higher order polynomials may be used for faster or more precise calculation:
73 // Order 1: log2(1+y) ~ y
74 // Order 2: log2(1+y) = (a*y + 1-a)*y, a=-0.3427
75 //  => max dev = +/- 8E-3, run time ~ ?
76 // Order 3: log2(1+y) = ((a*y+b)*y + 1-a-b)*y, a=0.1564, b=-0.5773
77 //  => max dev = +/- 1E-3, run time ~ ?
78 // Order 4: log2(1+y) = (((a*y+b)*y+c)*y + 1-a-b-c)*y, a=-0.0803 b=0.3170 c=-0.6748
79 //  => max dev = +/- 1.4E-4, run time ~ ?
80 // Order 5: log2(1+y) = ((((a*y+b)*y+c)*y+d)*y + 1-a-b-c-d)*y,
81 //     a=0.0440047 b=-0.1903190 c=0.4123442 d=-0.7077702 1-a-b-c-d=1.441740
82 //  => max dev = +/- 2.1E-5, run time ~ 1.2E-8s
flog2(float x)83 inline float flog2(float x) {
84   if (x <= 0)
85     return -128;
86   int *px = (int*) (&x);        // store address of float as pointer to long int
87   float e = (float) (((*px & 0x7F800000) >> 23) - 0x7f); // shift right by 23 bits and subtract 127 = 0x7f => exponent
88   *px = ((*px & 0x007FFFFF) | 0x3f800000);  // set exponent to 127 (i.e., 0)
89   x -= 1.0;         // and calculate x-1.0
90   x *= (1.441740
91       + x * (-0.7077702 + x * (0.4123442 + x * (-0.1903190 + x * 0.0440047)))); // 5'th order polynomial approx. of log(1+x)
92   return x + e;
93 }
94 
95 
96 // This function returns log2 with a max absolute deviation of +/- 1.5E-5 (typically 0.8E-5).
97 // It takes 0.80E-8 s  whereas log2(x) takes 5.4E-7 s. It is hence 9.4 times faster.
98 // It makes use of the representation of 4-byte floating point numbers:
99 // seee eeee emmm mmmm mmmm mmmm mmmm mmmm
100 // s is the sign,
101 // the following 8 bits, eee eee e, give the exponent + 127 (in hex: 0x7f).
102 // The following 23 bits give the mantisse, the binary digits after the decimal
103 // point:  x = (-1)^s * 1.mmmmmmmmmmmmmmmmmmmmmmm * 2^(eeeeeeee-127)
104 // In the code, *(int *)&x is an integer which contains the bytes as the
105 // floating point variable x is represented in memory. The expression
106 //     (((*(int *)&x) & 0x7f800000 ) >>23 )-0x7f is the exponent eeeeeeee,
107 // i.e., the largest integer that is smaller than log2(x) (e.g. -1 for 0.9).
fast_log2(float x)108 inline float fast_log2(float x) {
109   static float lg2[1025];         // lg2[i] = log2[1+x/1024]
110   static float diff[1025]; // diff[i]= (lg2[i+1]-lg2[i])/8096 (for interpolation)
111   static char initialized = 0;
112   if (x <= 0)
113     return -100000;
114   if (!initialized)   //First fill in the arrays lg2[i] and diff[i]
115   {
116     float prev = 0.0f;
117     lg2[0] = 0.0f;
118     for (int i = 1; i <= 1024; ++i) {
119       lg2[i] = log(float(1024 + i)) * 1.442695041 - 10.0f;
120       diff[i - 1] = (lg2[i] - prev) * 1.2352E-4;
121       prev = lg2[i];
122     }
123     initialized = 1;
124   }
125   int a = (((*((int *) &x)) & 0x7F800000) >> 23) - 0x7f; // exponent
126   int b = ((*((int *) &x)) & 0x007FE000) >> 13; // first 10 bits of mantisse
127   int c = ((*((int *) &x)) & 0x00001FFF);      // further 13 bits of mantisse
128   return a + lg2[b] + diff[b] * (float) (c);
129 }
130 
131 // This function returns log gamma and uses fast lookup table for computation.
132 // This function returns log gamma with a max abolute deviation of +/- 1E-5.
133 // It makes use of the representation of 4-byte floating point numbers:
134 // seee eeee emmm mmmm mmmm mmmm mmmm mmmm
135 // s is the sign,
136 // the following 8 bits, eee eee e, give the exponent + 127 (in hex: 0x7f).
137 // The following 23 bits, m, give the mantisse, the binary digits behind the decimal point.
138 // In summary: x = (-1)^s * 1.mmmmmmmmmmmmmmmmmmmmmm * 2^(eeeeeee-127)
139 // The expression (((*(int *)&x) & 0x7f800000 ) >>23 )-0x7f is the exponent eeeeeeee, i.e.
140 // the largest integer that is smaller than log2(x) (e.g. -1 for 0.9). *(int *)&x is an integer which
141 // contains the bytes as the floating point variable x is represented in memory.
142 // Check:  assert( sizeof(f) == sizeof(int) );
143 // Check:  assert( sizeof(f) == 4 );
fast_log_gamma(float x)144 inline float fast_log_gamma(float x) {
145   static float log_gamma[1025];   // log_gamma[i] = lgammaf(1+x/1024)
146   static float diff[1025]; // diff[i]= (lg2[i+1]-lg2[i])/8096 (for interpolation)
147   static char initialized = 0;
148 
149   if (!initialized) {  //First fill in the arrays log_gamma[i] and diff[i]
150     assert(x >= 1.0);
151     assert(sizeof(x) == sizeof(int));
152     assert(sizeof(x) == 4);
153 
154     float prev = 0.0f;
155     log_gamma[0] = 0.0f;
156     for (int i = 1; i <= 1024; ++i) {
157       log_gamma[i] = lgammaf(1.0f + i * 9.765625E-4);
158       diff[i - 1] = (log_gamma[i] - prev) * 1.2352E-4;
159       prev = log_gamma[i];
160     }
161     initialized = 1;
162   }
163 
164   float res = 1.0f;
165   float lres = 0.0f;
166   while (x >= 2.0f) {
167     x -= 1.0;
168     res *= x;
169     if (res > 1E30) {
170       lres += fast_log2(res);
171       res = 1.0f;
172     }
173   }
174   int b = ((*((int *) &x)) & 0x007FE000) >> 13; // exponent must be 0
175   int c = ((*((int *) &x)) & 0x00001FFF);
176   return (lres + fast_log2(res)) * 0.6931471806 + log_gamma[b]
177       + diff[b] * (float) (c);
178 }
179 
180 /////////////////////////////////////////////////////////////////////////////////////
181 // fast 2^x
182 // ATTENTION: need to compile with g++ -fno-strict-aliasing when using -O2 or -O3!!!
183 // Relative deviation < 4.6E-6  (< 2.3E-7 with 5'th order polynomial)
184 // Speed: 2.1E-8s (2.3E-8s) per call! (exp(): 8.5E-8, pow(): 1.7E-7)
185 // Internal representation of float number according to IEEE 754:
186 //   1bit sign, 8 bits exponent, 23 bits mantissa: seee eeee emmm mmmm mmmm mmmm mmmm mmmm
187 //                                    0x4b400000 = 0100 1011 0100 0000 0000 0000 0000 0000
188 //   In summary: x = (-1)^s * 1.mmmmmmmmmmmmmmmmmmmmmm * 2^(eeeeeee-127)
189 /////////////////////////////////////////////////////////////////////////////////////
fpow2(float x)190 inline float fpow2(float x)
191 {
192   if (x>=FLT_MAX_EXP) return FLT_MAX;
193   if (x<=FLT_MIN_EXP) return 0.0f;
194 
195   int *px = (int*) (&x);        // store address of float as pointer to long int
196   float tx = (x - 0.5f) + (3 << 22); // temporary value for truncation: x-0.5 is added to a large integer (3<<22),
197                                      // 3<<22 = (1.1bin)*2^23 = (1.1bin)*2^(150-127),
198                                      // which, in internal bits, is written 0x4b400000 (since 10010110bin = 150)
199   int lx = *((int*) &tx) - 0x4b400000;   // integer value of x
200   float dx = x - (float) (lx);             // float remainder of x
201 //   x = 1.0f + dx*(0.69606564f           // cubic apporoximation of 2^x for x in the range [0, 1]
202 //            + dx*(0.22449433f           // Gives relative deviation < 1.5E-4
203 //            + dx*(0.07944023f)));       // Speed: 1.9E-8s
204   x = 1.0f + dx * (0.693019f // polynomial approximation of 2^x for x in the range [0, 1]
205   + dx * (0.241404f             // Gives relative deviation < 4.6E-6
206   + dx * (0.0520749f            // Speed: 2.1E-8s
207   + dx * 0.0134929f)));
208 //   x = 1.0f + dx*(0.693153f             // polynomial apporoximation of 2^x for x in the range [0, 1]
209 //            + dx*(0.240153f             // Gives relative deviation < 2.3E-7
210 //            + dx*(0.0558282f            // Speed: 2.3E-8s
211 //            + dx*(0.00898898f
212 //            + dx* 0.00187682f ))));
213   *px += (lx << 23);                      // add integer power of 2 to exponent
214   return x;
215 }
216 
217 // Normalize a double array such that it sums to one
218 inline double normalize_to_one(double* array, size_t length,
219     const float* def_array = NULL) {
220   double sum = 0.0;
221   for (size_t k = 0; k < length; ++k)
222     sum += array[k];
223   if (sum != 0.0) {
224     double fac = 1.0 / sum;
225     for (size_t k = 0; k < length; ++k)
226       array[k] *= fac;
227   }
228   else if (def_array) {
229     for (size_t k = 0; k < length; ++k)
230       array[k] = def_array[k];
231   }
232   return sum;
233 }
234 
235 // Normalize a float array such that it sums to one
236 inline float normalize_to_one(float* array, size_t length,
237     const float* def_array = NULL) {
238   float sum = 0.0;
239   for (size_t k = 0; k < length; k++)
240     sum += array[k];
241   if (sum != 0.0) {
242     float fac = 1.0 / sum;
243     for (size_t k = 0; k < length; k++)
244       array[k] *= fac;
245   }
246   else if (def_array) {
247     for (size_t k = 0; k < length; ++k)
248       array[k] = def_array[k];
249   }
250   return sum;
251 }
252 
253 // Check if given filename is a regular file
is_regular_file(const char * fn)254 inline bool is_regular_file(const char *fn) {
255   bool ret = false;
256   struct stat fstats;
257   if (stat(fn, &fstats) == 0)
258     if (S_ISREG(fstats.st_mode))
259       ret = true;
260 
261   return ret;
262 }
263 
264 // Check if given path is a directory
is_directory(const char * fn)265 inline bool is_directory(const char *fn) {
266   bool ret = false;
267   struct stat fstats;
268   if (stat(fn, &fstats) == 0)
269     if (S_ISDIR(fstats.st_mode))
270       ret = true;
271 
272   return ret;
273 }
274 
275 // Normalize a float array such that it sums to one
276 // If it sums to 0 then assign def_array elements to array (optional)
277 inline float NormalizeTo1(float* array, int length, const float* def_array = NULL) {
278   float sum = 0.0f;
279   int k;
280   for (k = 0; k < length; k++)
281     sum += array[k];
282   if (sum != 0.0f) {
283     float fac = 1.0 / sum;
284     for (k = 0; k < length; k++)
285       array[k] *= fac;
286   }
287   else if (def_array)
288     for (k = 0; k < length; k++)
289       array[k] = def_array[k];
290   return sum;
291 }
292 
293 // Normalize a float array such that it sums to x
294 // If it sums to 0 then assign def_array elements to array (optional)
295 inline float NormalizeToX(float* array, int length, float x, float* def_array =
296     NULL) {
297   float sum = 0.0;
298   int k;
299   for (k = 0; k < length; k++)
300     sum += array[k];
301   if (sum) {
302     float fac = x / sum;
303     for (k = 0; k < length; k++)
304       array[k] *= fac;
305   }
306   else if (def_array)
307     for (k = 0; k < length; k++)
308       array[k] = def_array[k];
309   return sum;
310 }
311 
312 /////////////////////////////////////////////////////////////////////////////////////
313 // String utilities
314 /////////////////////////////////////////////////////////////////////////////////////
315 
316 // Safe strcpy command that limits copy to a maximum of maxlen+1 characters
317 // including the '\0' character.
318 // (Different from standard strncpy, which pads with \0 characters)
319 // Returns maxlen minus the number of non-\0 characters copied
320 // If the string is cut prematurely it will return 0!
strmcpy(char * dest,const char * source,size_t maxlen)321 inline int strmcpy(char* dest, const char* source, size_t maxlen) {
322   while (*source && (maxlen--) > 0)
323     *dest++ = *source++;
324   *dest = '\0';
325   return maxlen;
326 }
327 
328 // Scans string for integer number starting from ptr and returns this number.
329 // The ptr will then be moved to the first position after the integer number.
330 // If no integer number is found, it returns INT_MIN and sets ptr to NULL.
strtoi(const char * & ptr)331 inline int strtoi(const char*& ptr) {
332   int i;
333   const char* ptr0 = ptr;
334   if (!ptr)
335     return INT_MIN;
336   while (*ptr != '\0' && !(*ptr >= '0' && *ptr <= '9'))
337     ptr++;
338   if (*ptr == '\0') {
339     ptr = 0;
340     return INT_MIN;
341   }
342   if (*(ptr - 1) == '-' && ptr > ptr0)
343     i = -atoi(ptr);
344   else
345     i = atoi(ptr);
346   while (*ptr >= '0' && *ptr <= '9')
347     ptr++;
348   return i;
349 }
350 
351 //Same as strint, but interpretes '*' as default
352 inline int strtoi_(const char*& ptr, int deflt = INT_MAX) {
353   int i;
354   if (!ptr)
355     return INT_MIN;
356   while (*ptr != '\0' && !(*ptr >= '0' && *ptr <= '9') && *ptr != '*')
357     ptr++;
358   if (*ptr == '\0') {
359     ptr = 0;
360     return INT_MIN;
361   }
362   if (*ptr == '*') {
363     ptr++;
364     return deflt;
365   }
366   if (*(ptr - 1) == '-')
367     i = atoi(ptr - 1);
368   else
369     i = atoi(ptr);
370   while (*ptr >= '0' && *ptr <= '9')
371     ptr++;
372   return i;
373 }
374 
375 
376 // Removes the newline and other control characters at the end of a string (if present)
377 // and returns the new length of the string (-1 if str is NULL)
chomp(char str[])378 inline int chomp(char str[]) {
379   if (!str)
380     return -1;
381   int l = 0;
382   for (l = strlen(str) - 1; l >= 0 && str[l] < 32; l--)
383     ;
384   str[++l] = '\0';
385   return l;
386 }
387 
388 // Emulates the ifstream::getline method; similar to fgets(str,maxlen,FILE*),
389 // but removes the newline at the end and returns NULL if at end of file or read error
fgetline(char str[],const int maxlen,FILE * file)390 inline char* fgetline(char str[], const int maxlen, FILE* file) {
391   if (!fgets(str, maxlen, file))
392     return NULL;
393   if (chomp(str) + 1 >= maxlen)    // if line is cut after maxlen characters...
394     while (fgetc(file) != '\n')
395       ; // ... read in rest of line
396 
397   return (str);
398 }
399 
400 // Returns pointer to first non-white-space character in str OR to NULL if none found
strscn(char * str)401 inline char* strscn(char* str) {
402   if (!str)
403     return NULL;
404   char* ptr = str;
405   while (*ptr != '\0' && *ptr <= 32)
406     ptr++;
407   return (*ptr == '\0') ? NULL : ptr;
408 }
409 
410 // Returns pointer to first white-space character in str OR to NULL if none found
strscn_ws(char * str)411 inline char* strscn_ws(char* str) {
412   if (!str)
413     return NULL;
414   char* ptr = str;
415   while (*ptr != '\0' && *ptr > 32)
416     ptr++;
417   return (*ptr == '\0') ? NULL : ptr;
418 }
419 
420 //Returns pointer to first non-white-space character in str OR to NULL if none found
strscn_c(const char * str)421 inline const char* strscn_c(const char* str) {
422   if (!str)
423     return NULL;
424   const char* ptr = str;
425   while (*ptr != '\0' && isspace(*ptr))
426     ptr++;
427   return (*ptr == '\0') ? NULL : ptr;
428 }
429 
430 // Returns pointer to first  non-white-space character in str OR to end of string '\0' if none found
strscn_(char * str)431 inline char* strscn_(char* str) {
432   if (!str)
433     return NULL;
434   char* ptr = str;
435   while (*ptr != '\0' && *ptr <= 32)
436     ptr++;
437   return ptr;
438 }
439 
440 // Returns pointer to first non-c character in str OR to NULL if none found
strscn(char * str,const char c)441 inline char* strscn(char* str, const char c) {
442   if (!str)
443     return NULL;
444   char* ptr = str;
445   while (*ptr != '\0' && *ptr == c)
446     ptr++;
447   return (*ptr == '\0') ? NULL : ptr;
448 }
449 
450 // Returns pointer to first  non-c character in str OR to end of string '\0' if none found
strscn_(char * str,const char c)451 inline char* strscn_(char* str, const char c) {
452   if (!str)
453     return NULL;
454   char* ptr = str;
455   while (*ptr != '\0' && *ptr == c)
456     ptr++;
457   return ptr;
458 }
459 
460 // Cuts string at first white space character found by overwriting it with '\0'.
461 // Returns pointer to next non-white-space char OR to NULL if no such char found
strcut(char * str)462 inline char* strcut(char* str) {
463   if (!str)
464     return NULL;
465   char* ptr = str;
466   while (*ptr != '\0' && *ptr > 32)
467     ptr++;
468   if (*ptr == '\0')
469     return NULL;
470   *ptr = '\0';
471   ptr++;
472   while (*ptr != '\0' && *ptr <= 32)
473     ptr++;
474   return (*ptr == '\0') ? NULL : ptr;
475 }
476 
477 // Cuts string at first white space character found by overwriting it with '\0'.
478 // Returns pointer to next non-white-space char OR to end of string '\0' if none found
strcut_(char * str)479 inline char* strcut_(char* str) {
480   if (!str)
481     return NULL;
482   char* ptr = str;
483   while (*ptr != '\0' && *ptr > 32)
484     ptr++;
485   if (*ptr == '\0')
486     return ptr;
487   *ptr = '\0';
488   ptr++;
489   while (*ptr != '\0' && *ptr <= 32)
490     ptr++;
491   return ptr;
492 }
493 
494 // Cuts string at first occurence of charcter c, by overwriting it with '\0'.
495 // Returns pointer to next char not equal c, OR to NULL if none found
strcut(char * str,const char c)496 inline char* strcut(char* str, const char c) {
497   if (!str)
498     return NULL;
499   char* ptr = str;
500   while (*ptr != '\0' && *ptr != c)
501     ptr++;
502   if (*ptr == '\0')
503     return NULL;
504   *ptr = '\0';
505   ptr++;
506   while (*ptr != '\0' && *ptr == c)
507     ptr++;
508   return (*ptr == '\0') ? NULL : ptr;
509 }
510 
511 // Cuts string at first occurence of charcter c, by overwriting it with '\0'.
512 // Returns pointer to next char not equal c, OR to end of string '\0' if none found
strcut_(char * str,const char c)513 inline char* strcut_(char* str, const char c) {
514   if (!str)
515     return NULL;
516   char* ptr = str;
517   while (*ptr != '\0' && *ptr != c)
518     ptr++;
519   if (*ptr == '\0')
520     return ptr;
521   *ptr = '\0';
522   ptr++;
523   while (*ptr != '\0' && *ptr == c)
524     ptr++;
525   return ptr;
526 }
527 
528 // Cuts string at first occurence of substr, by overwriting the first letter with '\0'.
529 // Returns pointer to next char after occurence of substr, OR to NULL if no such char found
strcut(char * str,const char * substr)530 inline char* strcut(char* str, const char* substr) {
531   char* ptr;     //present location in str being compared to substr
532   const char* sptr = substr; //present location in substr being compared to substr
533   // while not at end of str and not all of substr is matched yet
534   while (1) {
535     for (ptr = str, sptr = substr; *ptr == *sptr && *ptr != '\0'; ptr++, sptr++)
536       ;
537     if (*sptr == '\0') {
538       *str = '\0';
539       return ptr;
540     }
541     if (*ptr == '\0')
542       return NULL;
543     str++;
544   }
545 }
546 
547 // Cuts string at first occurence of substr, by overwriting the first letter with '\0'.
548 // Returns pointer to next char after occurence of substr, OR to end of string '\0' if no such char found
strcut_(char * str,const char * substr)549 inline char* strcut_(char* str, const char* substr) {
550   char* ptr;         //present location in str being compared to substr
551   const char* sptr = substr; //present location in substr being compared to str
552   // while not at end of str and not all of substr is matched yet
553   while (1) {
554     for (ptr = str, sptr = substr; *ptr == *sptr && *ptr != '\0'; ptr++, sptr++)
555       ;
556     if (*sptr == '\0') {
557       *str = '\0';
558       return ptr;
559     }
560     if (*ptr == '\0')
561       return ptr;
562     str++;
563   }
564 }
565 
566 // Copies first word in ptr to str. In other words, copies first block of non whitespace characters,
567 // beginning at ptr, to str. If a word is found, returns address of second word in ptr or, if no second
568 // word is found, returns address to end of word ('\0' character) in ptr string. If no word is found
569 // in ptr NULL is returned.
strwrd(char * str,char * ptr)570 inline char* strwrd(char* str, char* ptr) {
571   ptr = strscn(ptr);    // advance to beginning of next word
572   if (ptr) {
573     while (*ptr != '\0' && *ptr > 32)
574       *(str++) = *(ptr++);
575     *str = '\0';
576     while (*ptr != '\0' && *ptr <= 32)
577       ptr++;
578     return ptr;
579   }
580   else
581     return NULL;
582 }
583 
584 // Copies first word in ptr to str. In other words, copies first block of non whitespace characters,
585 // beginning at ptr, to str. If a word is found, returns address of second word in ptr or, if no second
586 // word is found, returns address to end of word ('\0' character) in ptr string. If no word is found
587 // in ptr NULL is returned.
strwrd(char * str,char * ptr,int maxlen)588 inline char* strwrd(char* str, char* ptr, int maxlen) {
589   ptr = strscn(ptr);    // advance to beginning of next word
590   if (ptr) {
591     while (*ptr != '\0' && *ptr > 32 && (maxlen--) > 0)
592       *(str++) = *(ptr++);
593     *str = '\0';
594     while (*ptr != '\0' && *ptr <= 32)
595       ptr++;
596     return ptr;
597   }
598   else
599     return NULL;
600 }
601 
602 // Copies first word ***delimited by char c*** in ptr to str. In other words, copies first block of non-c characters,
603 // beginning at ptr, to str. If a word is found, returns address of second word in ptr or, if no second
604 // word is found, returns address to end of word ('\0' character) in ptr string. If no word is found
605 // in ptr NULL is returned.
strwrd(char * str,char * ptr,const char c)606 inline char* strwrd(char* str, char* ptr, const char c) {
607   ptr = strscn(ptr, c);    // advance to beginning of next word
608   if (ptr) {
609     while (*ptr != '\0' && *ptr != c)
610       *(str++) = *(ptr++);
611     *str = '\0';
612     while (*ptr != '\0' && *ptr == c)
613       ptr++;
614     return ptr;
615   }
616   else
617     return NULL;
618 }
619 
620 // transforms chr into an uppercase character
uprchr(char chr)621 inline char uprchr(char chr) {
622   return (chr >= 'a' && chr <= 'z') ? chr + 'A' - 'a' : chr;
623 }
624 
625 // transforms chr into an lowercase character
lwrchr(char chr)626 inline char lwrchr(char chr) {
627   return (chr >= 'A' && chr <= 'Z') ? chr - 'A' + 'a' : chr;
628 }
629 
630 // Replaces first occurence of str1 by str2 in str. Returns pointer to first occurence or NULL if not found
631 // ATTENTION: if str2 is longer than str1, allocated memory of str must be long enough!!
strsubst(char * str,const char str1[],const char str2[])632 inline char* strsubst(char* str, const char str1[], const char str2[]) {
633   char* ptr = strstr(str, str1);
634   strcpy(ptr, str2);
635   return ptr;
636 }
637 
638 
RemovePath(char outname[],char filename[])639 inline char* RemovePath(char outname[], char filename[]) {
640   char* ptr;
641 #ifdef WINDOWS
642   ptr=strrchr(filename,92);  //return adress for LAST \ (backslash) in name
643 #else
644   ptr = strrchr(filename, '/'); //return adress for LAST / in name
645 #endif
646   if (!ptr)
647     ptr = filename;
648   else
649     ptr++;
650   strcpy(outname, ptr);
651   return outname;
652 }
653 
RemoveExtension(char outname[],char filename[])654 inline char* RemoveExtension(char outname[], char filename[]) {
655   char *ptr1;
656   ptr1 = strrchr(filename, '.');       //return adress for LAST '.' in name
657   if (ptr1) {
658     *ptr1 = '\0';
659     strcpy(outname, filename);
660     *ptr1 = '.';
661   }
662   else
663     strcpy(outname, filename);
664   return outname;
665 }
666 
Extension(char extension[],const char * filename)667 inline char* Extension(char extension[], const char* filename) {
668   //return adress for LAST '.' in name
669   const char* ptr = strrchr(filename, '.');
670   if (ptr)
671     strcpy(extension, ptr + 1);
672   else
673     *extension = '\0';
674   return extension;
675 }
676 
677 // Path includes last '/'
Pathname(char pathname[],char filename[])678 inline char* Pathname(char pathname[], char filename[]) {
679   char* ptr;
680   char chr;
681 #ifdef WINDOWS
682   ptr=strrchr(filename,92);  //return adress for LAST \ (backslash) in name
683 #else
684   ptr = strrchr(filename, '/'); //return adress for LAST / in name
685 #endif
686   if (ptr) {
687     chr = *(++ptr);
688     *ptr = '\0';
689     strcpy(pathname, filename);
690     *ptr = chr;
691   }
692   else
693     *pathname = '\0';
694   return pathname;
695 }
696 
697 // Swaps two integer elements in array k
swapi(int k[],int i,int j)698 inline void swapi(int k[], int i, int j) {
699   int temp;
700   temp = k[i];
701   k[i] = k[j];
702   k[j] = temp;
703 }
704 
file_exists(const char * name)705 inline bool file_exists(const char* name) {
706   std::ifstream f(name);
707   if (f.good()) {
708     f.close();
709     return true;
710   }
711   else {
712     f.close();
713     return false;
714   }
715 }
716 
717 #endif /* UTIL_INL_H_ */
718