/*
   Copyright (C) 2011  Statoil ASA, Norway. 
    
   The file 'util.c' is part of ERT - Ensemble based Reservoir Tool. 
    
   ERT is free software: you can redistribute it and/or modify 
   it under the terms of the GNU General Public License as published by 
   the Free Software Foundation, either version 3 of the License, or 
   (at your option) any later version. 
    
   ERT is distributed in the hope that it will be useful, but WITHOUT ANY 
   WARRANTY; without even the implied warranty of MERCHANTABILITY or 
   FITNESS FOR A PARTICULAR PURPOSE.   
    
   See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> 
   for more details. 
*/

/**
  This file contains a large number of utility functions for memory
  handling, string handling and file handling. Observe that all these
  functions are just that - functions - there is no associated state
  with any of these functions.
  
  The file util_path.c is included in this, and contains path
  manipulation functions which explicitly use the PATH_SEP variable.
*/

#include <string.h>
#include <time.h>
#include <math.h>
#include <stdarg.h>
#include <stdio.h>

#include <fcntl.h>
#include <limits.h>

#ifdef HAVE_FORK
#ifdef WITH_PTHREAD
#ifdef HAVE_EXECINFO
#define HAVE_UTIL_ABORT
#endif
#endif
#endif

#ifdef HAVE_UTIL_ABORT
#define __USE_GNU       // Must be defined to get access to the dladdr() function; Man page says the symbol should be: _GNU_SOURCE but that does not seem to work?
#define _GNU_SOURCE     // Must be defined _before_ #include <errno.h> to get the symbol 'program_invocation_name'. 
#include <dlfcn.h>
#endif
#include <errno.h>

#include <stdint.h>
#include <ctype.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/stat.h>

#ifdef HAVE_OPENDIR
#include <dirent.h>
#endif

#ifdef HAVE_FNMATCH
#include <fnmatch.h>
#else
#include <Windows.h>
#include <Shlwapi.h>
#endif

#ifdef HAVE_FORK
#include <unistd.h>
#include <sys/wait.h>
#endif

#ifdef HAVE_USLEEP
#include <unistd.h>
#endif

#ifdef WITH_PTHREAD
#include <pthread.h>
#endif

#ifdef HAVE_EXECINFO
#include <execinfo.h>
#endif

#ifdef HAVE_FTRUNCATE
#include <unistd.h>
#include <sys/types.h>
#else
#include <io.h>
#endif


#include <stdint.h>
#if UINTPTR_MAX == 0xFFFFFFFF
#define ARCH32
#elif UINTPTR_MAX == 0xFFFFFFFFFFFFFFFF
#define ARCH64
#else
#error "Could not determine if this is a 32 bit or 64 bit computer?"
#endif

#include <ert/util/util.h>
#include <ert/util/buffer.h>


/*
   Macros for endian flipping. The macros create a new endian-flipped
   value, and should be used as: 

     flipped_value = FLIP32( value )
 
   The macros are not exported and only available through the function
   util_endian_flip_vector().  
*/


#define FLIP16(var) (((var >> 8) & 0x00ff) | ((var << 8) & 0xff00))

#define FLIP32(var) (( (var >> 24) & 0x000000ff) | \
                      ((var >>  8) & 0x0000ff00) | \
                      ((var <<  8) & 0x00ff0000) | \
                      ((var << 24) & 0xff000000))

#define FLIP64(var)  (((var >> 56) & 0x00000000000000ff) | \
                      ((var >> 40) & 0x000000000000ff00) | \
                      ((var >> 24) & 0x0000000000ff0000) | \
                      ((var >>  8) & 0x00000000ff000000) | \
                      ((var <<  8) & 0x000000ff00000000) | \
                      ((var << 24) & 0x0000ff0000000000) | \
                      ((var << 40) & 0x00ff000000000000) | \
                      ((var << 56) & 0xff00000000000000))




static uint16_t util_endian_convert16( uint16_t u ) {
  return (( u >> 8U ) & 0xFFU) | (( u & 0xFFU) >> 8U);
}


static uint32_t util_endian_convert32( uint32_t u ) {
  const uint32_t m8  = (uint32_t) 0x00FF00FFUL;
  const uint32_t m16 = (uint32_t) 0x0000FFFFUL;
  
  u = (( u >> 8U ) & m8)   | ((u & m8) << 8U);
  u = (( u >> 16U ) & m16) | ((u & m16) << 16U);
  return u;
}


static uint64_t util_endian_convert64( uint64_t u ) {
  const uint64_t m8  = (uint64_t) 0x00FF00FF00FF00FFULL;
  const uint64_t m16 = (uint64_t) 0x0000FFFF0000FFFFULL;
  const uint64_t m32 = (uint64_t) 0x00000000FFFFFFFFULL;

  
  u = (( u >> 8U ) & m8)   | ((u & m8) << 8U);
  u = (( u >> 16U ) & m16) | ((u & m16) << 16U);
  u = (( u >> 32U ) & m32) | ((u & m32) << 32U);
  return u;
}


static uint64_t util_endian_convert32_64( uint64_t u ) {
  const uint64_t m8  = (uint64_t) 0x00FF00FF00FF00FFULL;
  const uint64_t m16 = (uint64_t) 0x0000FFFF0000FFFFULL;

  
  u = (( u >> 8U ) & m8)   | ((u & m8) << 8U);
  u = (( u >> 16U ) & m16) | ((u & m16) << 16U);
  return u;
}



void util_endian_flip_vector(void *data, int element_size , int elements) {
  int i;
  switch (element_size) {
  case(1):
    break;
  case(2): 
    {
      uint16_t *tmp16 = (uint16_t *) data;

      for (i = 0; i <elements; i++)
        tmp16[i] = util_endian_convert16(tmp16[i]);
      break;
    }
  case(4):
    {
#ifdef ARCH64
      /*
        In the case of a 64 bit CPU the fastest way to swap 32 bit
        variables will be by swapping two elements in one operation;
        this is provided by the util_endian_convert32_64() function. In the case
        of binary ECLIPSE files this case is quite common, and
        therefor worth supporting as a special case. 
      */
      uint64_t *tmp64 = (uint64_t *) data;

      for (i = 0; i <elements/2; i++)
        tmp64[i] = util_endian_convert32_64(tmp64[i]);

      if ( elements & 1 ) {
        // Odd number of elements - flip the last element as an ordinary 32 bit swap.
        uint32_t *tmp32 = (uint32_t *) data;
        tmp32[ elements - 1] = util_endian_convert32( tmp32[elements - 1] );
      }
      break;
#else
      uint32_t *tmp32 = (uint32_t *) data;
      
      for (i = 0; i <elements; i++)
        tmp32[i] = util_endian_convert32(tmp32[i]);
      
      break;
#endif
    }
  case(8):
    {
      uint64_t *tmp64 = (uint64_t *) data;

      for (i = 0; i <elements; i++)
        tmp64[i] = util_endian_convert64(tmp64[i]);
      break;
    }
  default:
    fprintf(stderr,"%s: current element size: %d \n",__func__ , element_size);
    util_abort("%s: can only endian flip 1/2/4/8 byte variables - aborting \n",__func__);
  }
}

void util_endian_flip_vector_old(void *data, int element_size , int elements) {
  int i;
  switch (element_size) {
  case(1):
    break;
  case(2): 
    {
      uint16_t *tmp_int = (uint16_t *) data;

      for (i = 0; i <elements; i++)
        tmp_int[i] = FLIP16(tmp_int[i]);
      break;
    }
  case(4):
    {
      uint32_t *tmp_int = (uint32_t *) data;

      for (i = 0; i <elements; i++)
        tmp_int[i] = FLIP32(tmp_int[i]);
      
      break;
    }
  case(8):
    {
      uint64_t *tmp_int = (uint64_t *) data;

      for (i = 0; i <elements; i++)
        tmp_int[i] = FLIP64(tmp_int[i]);
      break;
    }
  default:
    fprintf(stderr,"%s: current element size: %d \n",__func__ , element_size);
    util_abort("%s: can only endian flip 1/2/4/8 byte variables - aborting \n",__func__);
  }
}

#ifndef S_ISDIR
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif


/*****************************************************************/

static bool EOL_CHAR(char c) {
  if (c == '\r' || c == '\n')
    return true;
  else
    return false;
}

#undef strncpy // This is for some reason needed in RH3


void util_fread_dev_random(int buffer_size , char * buffer) {
  FILE * stream = util_fopen("/dev/random" , "r");
  if (fread(buffer , 1 , buffer_size , stream) != buffer_size)
    util_abort("%s: failed to read:%d bytes from /dev/random \n",__func__ , buffer_size);
  
  fclose(stream);
}


void util_fread_dev_urandom(int buffer_size , char * buffer) {
  FILE * stream = util_fopen("/dev/urandom" , "r");
  if (fread(buffer , 1 , buffer_size , stream) != buffer_size)
    util_abort("%s: failed to read:%d bytes from /dev/random \n",__func__ , buffer_size);
  
  fclose(stream);
}


unsigned int util_clock_seed( ) {
  int sec,min,hour;
  int mday,year,month;
  time_t now = time( NULL );
  
  
  util_set_datetime_values(now , &sec , &min , &hour , &mday , &month , &year);
  {
    unsigned int seed = clock( );
    int i,j,k;
    for (i=0; i < 2*min + 2; i++) {
      for (j=0; j < 13*mday + 17; j++) {
        for (k=0; k < (hour + year + 17) * month + 13; k++) {
          seed *= (sec + min + mday);
        }
      }
    }
    return seed;
  }
}


/**
   Kahan summation is a technique to retain numerical precision when
   summing a long vector of values. See:
   http://en.wikipedia.org/wiki/Kahan_summation_algorithm 
*/

double util_kahan_sum(const double *data, size_t N) {
  double S = data[0];
  double C = 0;
  double Y,T;
  size_t i;
  
  for (i=1; i < N; i++) {
    Y = data[i] - C;
    T = S + Y;
    C = (T - S) - Y;
    S = T;
  }
  return S;
}


bool util_double_approx_equal( double d1 , double d2) {
  if (d1 == d2)
    return true;
  else {
    double epsilon = 1e-6;
    double diff = fabs(d1 - d2);
    double sum  = fabs(d1) + fabs(d2);
    
    if ((diff / sum) < epsilon)
      return true;
    else
      return false;
  }
}


char * util_alloc_substring_copy(const char *src , int offset , int N) {
  char *copy;
  if ((N + offset) < strlen(src)) {
    copy = util_calloc(N + 1 , sizeof * copy );
    strncpy(copy , &src[offset] , N);
    copy[N] = '\0';
  } else 
    copy = util_alloc_string_copy(&src[offset]);
  return copy;
}


char * util_alloc_dequoted_copy(const char *s) {
  char first_char = s[0];
  char last_char  = s[strlen(s) - 1];
  char *new;
  int offset , len;
  
  if ((first_char == '\'') || (first_char == '\"'))
    offset = 1;
  else 
    offset = 0;
  
  if ((last_char == '\'') || (last_char == '\"'))
    len = strlen(s) - offset - 1;
  else 
    len = strlen(s) - offset;
  
  new = util_alloc_substring_copy(s , offset , len);
  return new;
}



/**
   The input string is freed, and a new storage
   without quotes is returned. 
*/
char * util_realloc_dequoted_string(char *s) {
  char first_char = s[0];
  char last_char  = s[strlen(s) - 1];
  char *new;
  int offset , len;

  if ((first_char == '\'') || (first_char == '\"'))
    offset = 1;
  else 
    offset = 0;
  
  if ((last_char == '\'') || (last_char == '\"'))
    len = strlen(s) - offset - 1;
  else 
    len = strlen(s) - offset;
  
  new = util_alloc_substring_copy(s , offset , len);
  free(s);
  return new;
}

void util_strupr(char *s) {
  int i;
  for (i=0; i < strlen(s); i++)
    s[i] = toupper(s[i]);
}


char * util_alloc_strupr_copy(const char * s) {
  char * c = util_alloc_string_copy(s);
  util_strupr(c);
  return c;
}


/** 
    Replaces all occurences of c1 in s with c2.
*/
void util_string_tr(char * s, char c1, char c2) {
  int i;
  for (i=0; i < strlen(s);i++)
    if (s[i] == c1) s[i] = c2;
}


void util_rewind_line(FILE *stream) {
  bool at_eol = false;
  int c;

  do {
    if (ftell(stream) == 0)
      at_eol = true;
    else {
      fseek(stream , -1 , SEEK_CUR);
      c = fgetc(stream);
      at_eol = EOL_CHAR(c);
      if (!at_eol)
        fseek(stream , -1 , SEEK_CUR);
    }
  } while (!at_eol);
}



/**
   This function will reposition the stream pointer at the the first
   occurence of 'string'. If 'string' is found the function will
   return true, otherwise the function will return false, and stream
   pointer will be at the original position.

   If skip_string == true the stream position will be positioned
   immediately after the 'string', otherwise it will be positioned at
   the beginning of 'string'.

   If case_sensitive is true we require exact match with respect to
   case, otherwise we accept any case combination.
*/

bool util_fseek_string(FILE * stream , const char * __string , bool skip_string , bool case_sensitive) {
  bool string_found  = false;
  char * string      = util_alloc_string_copy(__string);

  if (!case_sensitive)
    util_strupr( string );
  {
    int len              = strlen( string );
    long int initial_pos = ftell( stream );   /* Store the inital position. */
    bool cont            = true;
    do {
      int c = fgetc( stream );
      if (!case_sensitive)
        c = toupper( c );
      
      if (c == string[0]) {  /* OK - we got the first character right - lets try in more detail: */
        long int current_pos  = ftell(stream);
        bool     equal        = true;
        int string_index;
        for (string_index = 1; string_index < len; string_index++) {
          c = fgetc( stream );
          if (!case_sensitive)
            c = toupper( c );
          
          if (c != string[string_index]) {
            equal = false;
            break;
          }
        }
        
        if (equal) {
          string_found = true;
          cont = false;
        } else /* Go back to current pos and continue searching. */
          fseek(stream , current_pos , SEEK_SET);
        
      }
      if (c == EOF) 
        cont = false;
    } while (cont);
    
    
    if (string_found) {
      if (!skip_string)
        fseek(stream , -strlen(string) , SEEK_CUR); /* Reposition to the beginning of 'string' */
    } else
      fseek(stream , initial_pos , SEEK_SET);       /* Could not find the string reposition at initial position. */
    
  }
  free( string );
  return string_found;
}



/**
  This function will allocate a character buffer, and read file
  content all the way up to 'stop_string'. If the stop_string is not
  found, the function will return NULL, and the file pointer will be
  unchanged.

  If include_stop_string is true the returned string will end with
  stop_string, and the file pointer will be positioned right AFTER
  stop_string, otherwise the file_pointer will be positioned right
  before stop_string.
*/



char * util_fscanf_alloc_upto(FILE * stream , const char * stop_string, bool include_stop_string) {
  long int start_pos = ftell(stream);
  if (util_fseek_string(stream , stop_string , include_stop_string , true)) {   /* Default case sensitive. */
    long int end_pos = ftell(stream);
    int      len     = end_pos - start_pos;
    char * buffer    = util_calloc( (len + 1) ,  sizeof * buffer );

    fseek(stream , start_pos , SEEK_SET);
    util_fread( buffer , 1 , len , stream , __func__);
    buffer[len] = '\0';
    
    return buffer;
  } else
    return NULL;   /* stop_string not found */
}



static char * util_fscanf_alloc_line__(FILE *stream , bool *at_eof , char * line) {
  int init_pos = ftell(stream);
  char * new_line;
  int len;
  char end_char;
  bool cont;
  bool dos_newline;
  
  len  = 0;
  cont = true;
  {
    char c;
    do {
      c = fgetc(stream);
      if (c == EOF) 
        cont = false;
      else {
        if (EOL_CHAR(c))
          cont = false;
        else
          len++;
      }
    } while (cont);
    if (c == '\r')
      dos_newline = true;
    else
      dos_newline = false;
    end_char = c;
  }
  
  if (fseek(stream , init_pos , SEEK_SET) != 0) 
    util_abort("%s: fseek failed: %d/%s \n",__func__ , errno , strerror(errno));

  new_line = util_realloc(line , len + 1 );
  util_fread(new_line , sizeof * new_line , len , stream , __func__);
  new_line[len] = '\0';
  

  /*
    Skipping the end of line marker(s).
  */

  fgetc(stream);
  if (dos_newline)
    fgetc(stream); 
 
  if (at_eof != NULL) {
    if (end_char == EOF)
      *at_eof = true;
    else
      *at_eof = false;
  }
  
  if (new_line != NULL) {
    char * strip_line = util_alloc_strip_copy(new_line);
    free(new_line);
    
    return strip_line;
  } else
    return NULL;
}


char * util_fscanf_alloc_line(FILE *stream , bool *at_eof) {
  return util_fscanf_alloc_line__(stream , at_eof , NULL);
}


char * util_fscanf_realloc_line(FILE *stream , bool *at_eof , char *line) {
  return util_fscanf_alloc_line__(stream , at_eof , line);
}



/**
   Reads characters from stdin until EOL/EOF is detected. A '\0' is
   appended to the resulting string before it is returned. If the
   function reads an immediate EOF/EOL, i.e. the user enters an empty
   input string, NULL (and not "") is returned.

   Observe that is this function does *not* cooperate very nicely with
   fscanf() based input, because fscanf will leave a EOL character in
   the input buffer, which will lead to immediate return from this
   function. Hence if this function is called after a fscanf() based
   function it is essential to preceede this function with one call to
   getchar() to clear the EOL character.
*/

char * util_alloc_stdin_line(void) {
  int input_size = 256;
  char * input   = util_calloc(input_size , sizeof * input );
  int index = 0;
  bool end = false;
  int c;
  do {
    c = getchar();
    if ((!EOL_CHAR(c)) && (c != EOF)) {
      input[index] = c;
      index++;
      if (index == (input_size - 1)) { /* Reserve space for terminating \0 */
        input_size *= 2;
        input = util_realloc(input , input_size );
      }
    } else end = true;
  } while (!end);
  if (index == 0) { 
    free(input);
    input = NULL;
  } else {
    input[index] = '\0';  
    input = util_realloc(input , strlen(input) + 1 );
  }
  
  return input;
}



char * util_realloc_stdin_line(char * p) {
  util_safe_free(p);
  return util_alloc_stdin_line();
}



/**
   WIndows does not have the usleep() function, on the other hand
   Sleep() function in windows has millisecond resolution, instead of
   seconds as in linux.
*/

void util_usleep( unsigned long micro_seconds ) {
#ifdef HAVE_USLEEP
  usleep( micro_seconds );
#else 
  #ifdef ERT_WINDOWS
  {
    int milli_seconds = micro_seconds / 1000;
    Sleep( milli_seconds );
  }
#endif
#endif
}


/**
   This function will allocate and read a line from stdin. If there is
   no input waiting on stdin (this typically only applies if stdin is
   redirected from a file/PIPE), the function will sleep for 'usec'
   microseconds and try again.
*/

char * util_blocking_alloc_stdin_line(unsigned long usec) {
  char * line;
  do {
    line = util_alloc_stdin_line();
    if (line == NULL) 
      util_usleep(usec);
  } while (line == NULL);
  return line;
}


char * util_alloc_cwd(void) {
  char * result_ptr;
  char * cwd;
  int buffer_size = 128;
  do {
    cwd = util_calloc(buffer_size , sizeof * cwd );
    result_ptr = getcwd(cwd , buffer_size - 1);
    if (result_ptr == NULL) {
      if (errno == ERANGE) {
        buffer_size *= 2;
        free(cwd);
      }
    }
  } while ( result_ptr == NULL );
  cwd = util_realloc(cwd , strlen(cwd) + 1 );
  return cwd;
}



bool util_is_cwd( const char * path ) {
  bool is_cwd = false;
  struct stat path_stat;

  if (stat(path , &path_stat) == 0) {
    if (S_ISDIR( path_stat.st_mode )) {
      char * cwd = util_alloc_cwd();
#ifdef ERT_WINDOWS
      /*
        The windows stat structure has the inode element, but it is
        not set. Actually - this is a property of the filesystem, and
        not the operating system - the whole check is probably broken?
      */
      util_abort("%s: Internal error - function not properly implmented on Windows \n",__func__);
#else
      struct stat cwd_stat;
      stat(cwd , &cwd_stat);
      if (cwd_stat.st_ino == path_stat.st_ino)
        is_cwd = true;
#endif
      free( cwd );
    }
  }
  return is_cwd;
}



/* 
   Homemade realpath() for not existing path or platforms without
   realpath().  
*/


static char * util_alloc_cwd_abs_path( const char * path ) {
  if (util_is_abs_path( path ))
    return util_alloc_string_copy( path );
  else {
    char * cwd       = util_alloc_cwd( );
    char * abs_path  = util_realloc( cwd , strlen( cwd ) + 1 + strlen( path ) + 1 );
    strcat( abs_path , UTIL_PATH_SEP_STRING );
    strcat( abs_path , path );
    return abs_path;
  }
}



/**
   Manual realpath() implementation to be used on platforms without
   realpath() support. Will remove /../, ./ and extra //. Will not
   handle symlinks.
*/


#define BACKREF ".."
#define CURRENT "."

char * util_alloc_realpath__(const char * input_path) {
  char * abs_path  = util_alloc_cwd_abs_path( input_path );
  char * real_path = util_malloc( strlen(abs_path) + 1 );
  real_path[0] = '\0';
  
  {
    bool  * mask;
    char ** path_list;
    int     path_len;

    util_path_split( abs_path , &path_len , &path_list );
    mask = util_malloc( path_len * sizeof * mask );
    {
      int i;
      for (i=0; i < path_len; i++)
        mask[i] = true;
    }
        
    {
      int path_index = 1;  // Path can not start with ..
      int prev_index = 0;
      while (true) {
        if (path_index == path_len)
          break;

        if (strcmp(path_list[path_index] , BACKREF ) == 0) {
          mask[path_index] = false;
          mask[prev_index] = false;
          prev_index--;
          path_index++;
        } else if (strcmp( path_list[path_index] , CURRENT) == 0) {
          mask[path_index] = false;
          path_index++;
        } else {
          path_index++;
          prev_index++;
          while (!mask[prev_index])
            prev_index++;
        }
      }

      /* Build up the new string. */
      {
        int i;
        for (i=0; i < path_len; i++) {
          if (mask[i]) {
            strcat( real_path , UTIL_PATH_SEP_STRING );
            strcat( real_path , path_list[i]);
          }
        }
      }
    }             
    free(mask);
    util_free_stringlist( path_list , path_len );
  }

  return real_path;
}

#undef BACKREF 
#undef CURRENT 



/**
   The util_alloc_realpath() will fail hard if the @input_path does
   not exist. If the path might-not-exist you should use
   util_alloc_abs_path() instead.  
*/


char * util_alloc_realpath(const char * input_path) {
#ifdef HAVE_REALPATH
  char * buffer   = util_calloc(PATH_MAX + 1 , sizeof * buffer );
  char * new_path = NULL;
  
  new_path = realpath( input_path , buffer);
  if (new_path == NULL) 
    util_abort("%s: input_path:%s - failed: %s(%d) \n",__func__ , input_path , strerror(errno) , errno);
  else 
    new_path = util_realloc(new_path , strlen(new_path) + 1);
  
  return new_path;
#else
  /* We do not have the realpath() implementation. Must first check if
     the entry exists; and if not we abort. If the entry indeed exists
     we call the util_alloc_cwd_abs_path() function: */
#ifdef HAVE_SYMLINK
  ERROR - What the fuck; have symlinks and not realpath()?!
#endif
  if (!util_entry_exists( input_path )) 
    util_abort("%s: input_path:%s does not exist - failed.\n",__func__ , input_path);
  
  return util_alloc_realpath__( input_path );
#endif 
}




/**
   If @path points to an existing entry the standard realpath()
   function is used otherwise an absolute path is created after the
   following simple algorithm:

    1. If @path starts with '/' the path is assumed to be absolute, and
       just returned.
  
    2. Else cwd is prepended to the path.

   In the manual realpath() neither "/../" nor symlinks are resolved. If path == NULL the function will return cwd().
*/

char * util_alloc_abs_path( const char * path ) {
  if (path == NULL)
    return util_alloc_cwd();
  else {
    if (util_entry_exists( path )) 
      return util_alloc_realpath( path );
    else
      return util_alloc_cwd_abs_path( path );
  }
}



/**
   Both path arguments must be absolute paths; if not a copy of the
   input path will be returned. Neither of the input arguments can
   have "/../" elements - that will just fuck things up.

   root_path can be NULL - in which case cwd is used.
*/

char * util_alloc_rel_path( const char * __root_path , const char * path) {
  char * root_path;
  if (__root_path == NULL)
    root_path = util_alloc_cwd();
  else
    root_path = util_alloc_string_copy( __root_path );

  if (util_is_abs_path(root_path) && util_is_abs_path(path)) {
    const char * back_path = "..";
    char * rel_path = util_alloc_string_copy("");  // In case strcmp(root_path , path) == 0 the empty string "" will be returned
    char ** root_path_list;
    char ** path_list;
    int     root_path_length , path_length , back_length;

    /* 1. Split both input paths into list of path elements. */
    util_path_split( root_path, &root_path_length  , &root_path_list );
    util_path_split( path     , &path_length       , &path_list      );
    
    {
      /* 2: Determine the number of common leading path elements. */
      int common_length = 0;
      while (true) {
        if (strcmp(root_path_list[common_length] , path_list[common_length]) == 0)
          common_length++;
        else
          break;
        
        if (common_length == util_int_min( root_path_length , path_length))
          break;
      }
      
      /* 3: Start building up the relative path with leading ../ elements. */
      back_length = root_path_length - common_length;
      if (back_length > 0) {
        int i; 
        for (i=0; i < back_length; i++) {
          rel_path = util_strcat_realloc( rel_path , back_path );
          rel_path = util_strcat_realloc( rel_path , UTIL_PATH_SEP_STRING );
        }        
      }

      /* 4: Add the remaining elements from the input path. */
      {
        int i;
        for (i=common_length; i < path_length; i++) {
          rel_path = util_strcat_realloc( rel_path , path_list[i] );
          if (i != (path_length - 1))
            rel_path = util_strcat_realloc( rel_path , UTIL_PATH_SEP_STRING );
        }
      }
    }
    
    util_free_stringlist( root_path_list , root_path_length );
    util_free_stringlist( path_list , path_length );
    free( root_path );

    if (strlen(rel_path) == 0) {
      free(rel_path);
      rel_path = NULL;
    } return rel_path;
  } else {
    /* 
       One or both the input arguments do not correspond to an
       absolute path; just return a copy of the input back.
    */
    free( root_path );
    return util_alloc_string_copy( path );
  }
}




/**
   This function will allocate a string copy of the env_index'th
   occurence of an embedded environment variable from the input
   string. 

   An environment variable is defined as follows:

     1. It starts with '$'.
     2. It ends with a characeter NOT in the set [a-Z,0-9,_].

   The function will return environment variable number 'env_index'. If
   no such environment variable can be found in the string the
   function will return NULL. 

   Observe that the returned string will start with '$'. This is to
   simplify subsequent calls to util_string_replace_XXX() functions,
   however &ret_value[1] must be used in the subsequent getenv() call:

   { 
      char * env_var = util_isscanf_alloc_envvar( s , 0 ); 
      if (env_var != NULL) {
         const char * env_value = getenv( &env_var[1] );   // Skip the leading '$'.
         if (env_value != NULL)
            util_string_replace_inplace( s , env_value );
         else
            fprintf(stderr,"** Warning: environment variable: \'%s\' is not defined \n", env_var);
         free( env_var );
      }
   }


*/

char * util_isscanf_alloc_envvar( const char * string , int env_index ) {
  int env_count = 0;
  const char * offset = string;
  char       * env_ptr;
  do {
    env_ptr = strchr( offset , '$' );
    offset = &env_ptr[1];
    env_count++;
  } while ((env_count <= env_index) && (env_ptr != NULL));

  if (env_ptr != NULL) {
    /* 
       We found an environment variable we are interested in. Find the
       end of this variable and return a copy.
    */  
    int length = 1;
    bool cont  = true;
    do {
      
      if ( !( isalnum(env_ptr[length]) || env_ptr[length] == '_' ))
        cont = false;
      else
        length++;
      if (length == strlen( env_ptr ))
        cont = false;
    } while (cont);
    
    return util_alloc_substring_copy( env_ptr , 0 , length );
  } else
    return NULL; /* Could not find any env variable occurences. */
}







void util_fskip_lines(FILE * stream , int lines) {
  bool cont = true;
  int line_nr = 0;
  do {
    bool at_eof = false;
    char c;
    do {
      c = fgetc(stream);
      if (c == EOF)
        at_eof = true;
    } while (c != '\r' && c != '\n' && !at_eof);

    /* 
       If we have read a \r this is quite probably a DOS formatted
       file, and we read another character in the anticipation that it
       is a \n character.
    */
    if (c == '\r') {
      c = fgetc( stream );
      if (c == EOF)
        at_eof = true;
      else {
        if (c != '\n')
          fseek( stream , -1 , SEEK_CUR );
      }
    }
    
    line_nr++;
    if (line_nr == lines || at_eof) cont = false;
  } while (cont);
}
            

/*
  The last line(s) without content are not counted, i.e.

  File:
  ----------
  |Line1
  |Line2
  |
  |Line4
  |empty1
  |empty2
  |empty3

  will return a value of four.
*/
  
int util_forward_line(FILE * stream , bool * at_eof) {
  bool at_eol = false;
  int col = 0;
  *at_eof     = false;
  
  do {
    char c = fgetc(stream);
    if (c == EOF) {
      *at_eof = true;
      at_eol  = true;
    } else {
      if (EOL_CHAR(c)) {
        at_eol = true;
        c = fgetc(stream);
        if (c == EOF) 
          *at_eof = true;
        else {
          if (!EOL_CHAR(c)) 
            fseek(stream , -1 , SEEK_CUR);
        }
      } else
        col++;
    }
  } while (!at_eol);
  return col;
}



bool util_char_in(char c , int set_size , const char * set) {
  int i;
  bool in = false;
  for (i=0; i < set_size; i++)
    if (set[i] == c)
      in = true;
  
  return in;
}


/** 
    Returns true if ALL the characters in 's' return true from
    isspace().
*/
bool util_string_isspace(const char * s) {
  int  index = 0;
  while (index < strlen(s)) {
    if (!isspace( s[index] ))
      return false;
    index++;
  }
  return true;
}


void util_fskip_token(FILE * stream) {
  char * tmp = util_fscanf_alloc_token(stream);
  if (tmp != NULL)
    free(tmp);
}



static void util_fskip_chars__(FILE * stream , const char * skip_set , bool complimentary_set , bool *at_eof) {
  bool cont     = true;
  do {
    int c = fgetc(stream);
    if (c == EOF) {
      *at_eof = true;
      cont = false;
    } else {
      if (strchr(skip_set , c) == NULL) {
        /* c is not in skip_set */
        if (!complimentary_set)
          cont = false;
      } else {
        /* c is in skip_set */
        if (complimentary_set)
          cont = false;
      }
    }
  } while (cont);
  if (!*at_eof)
    fseek(stream , -1 , SEEK_CUR);
}


void util_fskip_chars(FILE * stream , const char * skip_set , bool *at_eof) {
  util_fskip_chars__(stream , skip_set , false , at_eof);
}

void util_fskip_cchars(FILE * stream , const char * skip_set , bool *at_eof) {
  util_fskip_chars__(stream , skip_set , true , at_eof);
}


static void util_fskip_space__(FILE * stream , bool complimentary_set , bool *at_eof) {
  bool cont     = true;
  do {
    int c = fgetc(stream);
    if (c == EOF) {
      *at_eof = true;
      cont = false;
    } else {
      if (!isspace(c)) {
        /* c is not in space set. */
        if (!complimentary_set)
          cont = false;
      } else {
        /* c is in skip_set */
        if (complimentary_set)
          cont = false;
      }
    }
  } while (cont);
  if (!*at_eof)
    fseek(stream , -1 , SEEK_CUR);
}


void util_fskip_space(FILE * stream ,  bool *at_eof) {
  util_fskip_space__(stream , false , at_eof);
}




/** 
    This functions reads a token[1] from stream, allocates storage for
    the it, and returns the newly allocated storage. Observe that the
    function does *NOT* read past end of line. If no token can be the
    function will return NULL.

    Example:
    --------

    File:
     ________________
    /
    | This is a file
    | Line2
    | Line3
    \________________


   bool at_eof = 0;
   char * token;
   while (!at_eof) {
      token = util_fscanf_alloc_token(stream);
      if (token != NULL) {
         printf("Have read token:%s \n",token);  
         free(token);
      } else {
         printf("Have reached EOL/EOF \n");
         util_forward_line(stream , &at_eof);
      }
   }

   This will produce the output:
   Have read token: This
   Have read token: is
   Have read token: a 
   Have read token: file
   Have reached EOL/EOF
   Have read token: Line2
   Have reached EOL/EOF
   Have read token: Line3
   Have reached EOL/EOF


   [1]: A token is defined as a sequence of characters separated by
    white-space or tab.
*/
    



char * util_fscanf_alloc_token(FILE * stream) {
  const char * space_set = " \t";
  bool cont;
  char * token = NULL;
  char c;

  
  cont = true;

  /* Skipping initial whitespace */
  do {
    int pos = ftell(stream);
    c = fgetc(stream);
    if (EOL_CHAR(c)) {
      /* Going back to position at newline */
      fseek(stream , pos , SEEK_SET);
      cont = false;
    } else if (c == EOF) 
      cont = false;
    else if (!util_char_in(c , 2 , space_set)) {
      fseek(stream , pos , SEEK_SET);
      cont = false;
    }
  } while (cont);
  if (EOL_CHAR(c)) return NULL;
  if (c == EOF)    return NULL;

  

  /* At this point we are guranteed to return something != NULL */
  cont = true;
  {
    int length = 0;
    long int token_start = ftell(stream);

    do {
      c = fgetc(stream);
      if (c == EOF)
        cont = false;
      else if (EOL_CHAR(c))
        cont = false;
      else if (util_char_in(c , 2 , space_set))
        cont = false;
      else
        length++;
    } while (cont);
    if (EOL_CHAR(c)) fseek(stream , -1 , SEEK_CUR);
  
    token = util_calloc(length + 1 , sizeof * token );
    fseek(stream , token_start , SEEK_SET);
    { 
      int i;
      for (i = 0; i < length; i++)
        token[i] = fgetc(stream);
      token[length] = '\0';
    }
  }
  return token;
}



/**
  This function parses a string literal (hopfully) containing a
  represantation of a double. The return value is true|false depending
  on the success of the parse operation, the parsed value is returned
  by reference.


  Example:
  --------
  const char * s = "78.92"
  double value;
  
  if (util_sscanf_double(s , &value)) 
    printf("%s is a valid double\n");
  else
    printf("%s is NOT a valid double\n");

*/
 
bool util_sscanf_double(const char * buffer , double * value) { 
  bool value_OK = false; 
  char * error_ptr;

  double tmp_value = strtod(buffer , &error_ptr);
  /*
    Skip trailing white-space
  */
  while (error_ptr[0] != '\0' && isspace(error_ptr[0]))
    error_ptr++;
  
  if (error_ptr[0] == '\0') {
    value_OK = true; 
    if (value != NULL)
      *value = tmp_value;
  } 
  return value_OK;
}


/**
   Base 8
*/

bool util_sscanf_octal_int(const char * buffer , unsigned int * value) {
  bool value_OK = false;
  char * error_ptr;

  int tmp_value = strtol(buffer , &error_ptr , 8);
  
  /*
    Skip trailing white-space
  */

  while (error_ptr[0] != '\0' && isspace(error_ptr[0]))
    error_ptr++;

  if (error_ptr[0] == '\0') {
    value_OK = true; 
    if (value != NULL)
      *value = tmp_value;
  } 
  return value_OK;
}



/**
   Takes a char buffer as input, and parses it as an integer. Returns
   true if the parsing succeeded, and false otherwise. If parsing
   succeded, the integer value is returned by reference.
*/

bool util_sscanf_int(const char * buffer , int * value) {
  bool value_OK = false;
  char * error_ptr;

  int tmp_value = strtol(buffer , &error_ptr , 10);

  /*
    Skip trailing white-space
  */

  while (error_ptr[0] != '\0' && isspace(error_ptr[0]))
    error_ptr++;

  if (error_ptr[0] == '\0') {
    value_OK = true; 
    if (value != NULL)
      *value = tmp_value;
  } 
  return value_OK;
}

/*
  If any (or both) s1 or s2 is equal to NULL - the function will
  return false.
*/

bool util_string_equal(const char * s1 , const char * s2 ) {
  if (s1 == NULL || s2 == NULL) 
    return false;
  
  /* Now we know that BOTH s1 and s2 are != NULL */
  if (strcmp(s1,s2) == 0)
    return true;
  else
    return false;
}



/**
   This function parses the string 's' for an integer. The return
   value is a pointer to the first character which is not an integer
   literal, or NULL if the whole string is read.

   The actual integer value is returned by reference. In addition a
   bool 'OK' is returned by reference, observe that that the bool OK
   is checked on function entry, and must point to true then.

   The somewhat contrived interface is to facilitate repeated calls on
   the same string to get out all the integers, typically to be used
   together with util_skip_sep().

   Example
   -------

   s = "1, 10, 78, 67";
         |   |   |   NULL
         1   2   3   3
         
   The vertical bars indicate the return values.         

*/

  
const char * util_parse_int(const char * s , int * value, bool *OK) {
  if (*OK) {
    char * error_ptr;
    *value = strtol(s , &error_ptr , 10);
    if (error_ptr == s) *OK = false;
    return error_ptr;
  } else
    return NULL;
}



/**
   This function will skip the characters in s which are in the string
   'sep_set' and return a pointer to the first character NOT in
   'sep_set'; this is basically strspn() functionality. But it will
   update a reference bool OK if no characters are skipped -
   i.e. there should be some characters to skip. Typically used
   together with util_parse_int():


   Example
   -------

   const char * s = "1, 6 , 79 , 89 , 782";
   const char * current_ptr = s;
   bool OK = true;
   while (OK) {
      int value;
      current_ptr = util_parse_int(current_ptr , &value , &OK);
      if (OK) 
         printf("Found:%d \n",value);
      current_ptr = util_skip_sep(current_ptr , " ," , &OK);
   }

   
*/

const char * util_skip_sep(const char * s, const char * sep_set, bool *OK) {
  if (*OK) {
    int sep_length = strspn(s , sep_set);
    if (sep_length == 0)
      *OK = false;
    return &s[sep_length];
  } else 
    return NULL;
}





/**
   This function will parse string containing an integer, and an
   optional suffix. The valid suffizes are KB,MB and GB (any case is
   allowed); if no suffix is appended the buffer is assumed to contain
   a memory size already specified in bytes.
   

   Observe that __this_function__ allows an arbitrary number of spaces
   between between the integer literal and the suffix string; however
   this might be tricky when parsing. It is probably best to disallow
   these spaces?

   "1GB", "1 GB", "1    gB"

   are all legitimate. The universal factor used is 1024:

      KB => *= 1024
      MB => *= 1024 * 1024;
      GB => *= 1024 * 1024 * 1024;
      
   Observe that if the functions fails to parse/interpret the string
   it will return false, and set the reference value to 0. However it
   will not fail with an abort. Overflows are *NOT* checked for.
*/


bool util_sscanf_bytesize(const char * buffer, size_t *size) {
  size_t value;
  char * suffix_ptr;
  size_t KB_factor = 1024;
  size_t MB_factor = 1024 * 1024;
  size_t GB_factor = 1024 * 1024 * 1024;
  size_t factor    = 1;
  bool   parse_OK  = true;

  value = strtol(buffer , &suffix_ptr , 10);
  if (suffix_ptr[0] != '\0') {
    while (isspace(suffix_ptr[0])) 
      suffix_ptr++;
    {
      char * upper = util_alloc_string_copy(suffix_ptr);
      if (strcmp(upper,"KB") == 0)
        factor = KB_factor;
      else if (strcmp(upper,"MB") == 0)
        factor = MB_factor;
      else if (strcmp(upper , "GB") == 0)
        factor = GB_factor;
      else
        parse_OK = false;
      /* else - failed to parse - returning false. */
      free(upper);
    }
  } 

  if (size != NULL) {
    if (parse_OK)
      *size = value * factor;
    else
      *size = 0;
  }
  
  return parse_OK;
}


/**
   Checks if c is in the character class: [-0-9], and optionally "."
*/

static int isnumeric( int c , bool float_mode) {
  if (isdigit( c ))
    return true;
  else {
    if (c == '-')
      return true;
    else if (float_mode && (c == '.'))
      return true;
    else
      return false;
  }
}

/**
   Will compare two strings by using a mix of ordinary strcmp() and
   numerical comparison. The algorithm works like this:

   while (equal) {
      1. Scan both characters until character difference is found:
      2. Both characters numeric?

           Yes: use strtol()/strtod() to read embedded numeric string,
                and do a numerical comparison.

           No:  normal strcmp( ) of the two strings.

       Whether a character is numeric is tested with isnumeric()
       function.
   }

   Caveats: 
   
     o Algorithm will not interpret "-" as a minus sign, only as a
       character. This might lead to unexpected results if you want to
       compare strings with embedded signed numeric literals, see
       example three below.
   
   Examples:
   
   S1           S2            util_strcmp_numeric()    strcmp()
   ------------------------------------------------------------
   "001"        "1"           0                        -1
   "String-10"  "String-3"    1                        -1                
   "String-8"   "String1"     -1                       -1
   ------------------------------------------------------------
*/
   

static int util_strcmp_numeric__( const char * s1 , const char * s2, bool float_mode) {
  /* 
     Special case to handle e.g.

         util_strcmp_numeric("100.00000" , "100") 

     which should compare as equal. The normal algorithm will compare
     equal characterwise all the way until one string ends, and the
     shorter string will be returned as less than the longer - without
     ever invoking the numerical comparison.
  */
  {
    double num1 , num2;
    char * end1;
    char * end2;
    
    if (float_mode) {
      num1 = strtod( s1 , &end1 );
      num2 = strtod( s2 , &end2 );
    } else {
      num1 = 1.0 * strtol( s1 , &end1  , 10);
      num2 = 1.0 * strtol( s2 , &end2  , 10);
    }
    
    if ( (*end2 == '\0') && (*end1 == '\0')) {  
      /* The whole string has been read and converted to a number - for both strings. */
      if (num1 < num2)
        return -1;
      else if (num1 > num2) 
        return 1;
      else
        return 0;
    } 
  } 
  
  
  /* 
     At least one of the strings is not a pure numerical literal and
     we start on a normal comparison. 
  */
  {
    int cmp       = 0;
    bool complete = false;  
    int  len1     = strlen( s1 );
    int  len2     = strlen( s2 );
    int  offset1  = 0;
    int  offset2  = 0;
    
    
    while (!complete) {
      while( true ) {
        if ((offset1 == len1) || (offset2 == len2)) {
          /* OK - at least one of the strings is at the end;
             we set the cmp value and return. */
          
          if ((offset1 == len1) && (offset2 == len2))
            /* We are the the end of both strings - they compare as equal. */
            cmp = 0;
          else if (offset1 == len1)
            cmp = -1;  // s1 < s2
          else
            cmp = 1;   // s1 > s2
          complete = true;
          break;
        }
        
        if (s1[offset1] != s2[offset2])
          /* We have reached a point of difference, jump out of this
             loop and continue with more detailed comparison further
             down. */
          break;
        
        // Strings are still equal - proceed one character further.
        offset1++;
        offset2++;
      }
      
      if (!complete) {
        /* 
           Both offset values point to a valid character value, but the
           two character values are different:
           
           1. Both characters are numeric - we use strtol() to read the
              two integers and perform a numeric comparison.
           
           2. One or none of the characters are numeric, we just use
              ordinary strcmp() on the substrings starting at the current
              offset.
        */
        
        if (isnumeric( s1[ offset1 ] , float_mode) && isnumeric( s2[ offset2 ] , float_mode)) {
          char * end1;
          char * end2;
          double num1,num2;
          /* 
             The numerical comparison is based on double variables
             irrespective of the value of @float_mode. 
          */
          if (float_mode) {
            num1 = strtod( &s1[ offset1 ] , &end1 );
            num2 = strtod( &s2[ offset2 ] , &end2 );
          } else {
            num1 = 1.0 * strtol( &s1[ offset1 ] , &end1  , 10);
            num2 = 1.0 * strtol( &s2[ offset2 ] , &end2  , 10);
          }
        
          if (num1 != num2) {
            if (num1 < num2)
              cmp = -1;
            else
              cmp = 1;
            complete = true;
          } else {
            /* The two numeric values are identical and we must
               continue. Start by using the end pointers to determine
               new offset values. If the end pointers are NULL that
               means the whole string has been devoured, and we can set
               the offset to point to the end of the string.
            */
            if (end1 == NULL)
              offset1 = len1;
            else
              offset1 = end1 - s1;

            if (end2 == NULL)
              offset2 = len2;
            else
              offset2 = end2 - s2;
          }
        } else {
          /* 
             We have arrived at a point of difference in the string, and
             perform 100% standard strcmp().
          */
          cmp = strcmp( &s1[offset1] , &s2[offset2] );
          complete = true;
        } 
      }
    }
    return cmp;
  }
}

/**
   Will interpret XXXX.yyyy as a fractional number.
*/
int util_strcmp_float( const char * s1 , const char * s2) {
  return util_strcmp_numeric__( s1 , s2 , true );
}


/*
   Will interpret XXXX.yyyy as two integers.
*/

int util_strcmp_int( const char * s1 , const char * s2) {
  return util_strcmp_numeric__( s1 , s2 , false );
}



/** 
    Succesfully parses:

      1 , T (not 't') , True (with any case) => true
      0 , F (not 'f') , False(with any case) => false
      
    Else the parsing fails.
*/


bool util_sscanf_bool(const char * buffer , bool * _value) {
  bool parse_OK = false;
  bool value    = false; /* Compiler shut up */

  if (strcmp(buffer,"1") == 0) {
    parse_OK = true;
    value = true;
  } else if (strcmp(buffer , "0") == 0) {
    parse_OK = true;
    value = false;
  } else if (strcmp(buffer , "T") == 0) {
    parse_OK = true;
    value = true;
  } else if (strcmp(buffer , "F") == 0) {
    parse_OK = true;
    value = false;
  } else {
    char * local_buffer = util_alloc_string_copy(buffer);
    util_strupr(local_buffer);
    
    if (strcmp(local_buffer , "TRUE") == 0) {
      parse_OK = true;
      value = true;
    } else if (strcmp(local_buffer , "FALSE") == 0) {
      parse_OK = true;
      value = false;
    } 

    free(local_buffer);
  }
  if (_value != NULL)
    *_value = value;
  return parse_OK;
}


bool util_fscanf_bool(FILE * stream , bool * value) {
  char buffer[256];
  fscanf(stream , "%s" , buffer);
  return util_sscanf_bool( buffer , value );
}


/**
   Takes a stream as input. Reads one string token from the stream,
   and tries to interpret the token as an integer with the function
   util_sscanf_int(). Returns true if the parsing succeeded, and false
   otherwise. If parsing succeded, the integer value is returned by
   reference.

   If the parsing fails the stream is repositioned at the location it
   had on entry to the function.
*/
   

bool util_fscanf_int(FILE * stream , int * value) {
  long int start_pos = ftell(stream);
  char * token       = util_fscanf_alloc_token(stream);
  
  bool   value_OK = false;
  if (token != NULL) {
    value_OK = util_sscanf_int(token , value);
    if (!value_OK)
      fseek(stream , start_pos , SEEK_SET);
    free(token);
  }
  return value_OK;
}   


/**
   Prompt .........====>
   <-------1------><-2-> 

   The section marked with 1 above is the prompt length, i.e. the
   input prompt is padded wth one blank, and then padded with
   'fill_char' (in the case above that is '.') characters up to a
   total length of prompt_len. Then the the termination string ("===>"
   above) is added. Observe the following:

   * A space is _always_ added after the prompt, before the fill char
     comes, even if the prompt is too long in the first place.

   * No space is added at the end of the termination string. If
     you want a space, that should be included in the termination
     string.

*/


void util_printf_prompt(const char * prompt , int prompt_len, char fill_char , const char * termination) {
  int current_len = strlen(prompt) + 1;
  printf("%s ",prompt);  /* Observe that one ' ' is forced in here. */ 
  
  while (current_len < prompt_len) {
    fputc(fill_char , stdout);
    current_len++;
  }
  printf("%s" , termination);

}


/**
   This functions presents the user with a prompt, and reads an
   integer - the integer value is returned. The functions returns
   NULL on empty input.
*/

int util_scanf_int(const char * prompt , int prompt_len) {
  char input[256];
  int  int_value;
  bool OK;
  do {
    util_printf_prompt(prompt , prompt_len, '=', "=> ");
    scanf("%s" , input);
    OK = util_sscanf_int(input , &int_value);
  } while (!OK);
  getchar(); /* eating a \r left in the stdin input buffer. */
  return int_value;
}

/**
   This functions presents the user with a prompt, and reads an
   integer - the integer value is returned. The functions will loop
   indefinitely until a valid integer is entered.
*/

char * util_scanf_int_return_char(const char * prompt , int prompt_len) {
  char input[256];
  int  int_value;
  bool OK = false;
  while(!OK){
    util_printf_prompt(prompt , prompt_len, '=', "=> ");
    fgets(input, prompt_len, stdin);
    {
                char *newline = strchr(input,'\n');
                if(newline)
                        *newline = 0;
        }

    if(strlen(input) !=0){
      OK = util_sscanf_int(input , &int_value);
    }
    else {
      OK = true;
    }
  }
  return util_alloc_string_copy(input);
}


double util_scanf_double(const char * prompt , int prompt_len) {
  char input[256];
  double  double_value;
  bool OK;
  do {
    util_printf_prompt(prompt , prompt_len, '=', "=> ");
    scanf("%s" , input);
    OK = util_sscanf_double(input , &double_value);
  } while (!OK);
  getchar(); /* eating a \r left in the stdin input buffer. */
  return double_value;
}







/** 
    The limits are inclusive.
*/
int util_scanf_int_with_limits(const char * prompt , int prompt_len , int min_value , int max_value) {
  int value;
  char * new_prompt = util_alloc_sprintf("%s [%d:%d]" , prompt , min_value , max_value);
  do {
    value = util_scanf_int(new_prompt , prompt_len);
  } while (value < min_value || value > max_value);
  free(new_prompt);
  return value;
}

/** 
    The limits are inclusive, yet the function returns the input char and stops on empty string.
*/
char * util_scanf_int_with_limits_return_char(const char * prompt , int prompt_len , int min_value , int max_value) {
  int value = min_value - 1;
  char * value_char = NULL;
  char * new_prompt = util_alloc_sprintf("%s [%d:%d]" , prompt , min_value , max_value);
  while( value < min_value || value > max_value ){
    value_char = util_scanf_int_return_char(new_prompt , prompt_len);
    if (strlen(value_char) == 0)
      value = min_value;
    else
      util_sscanf_int(value_char , &value);
  }
  free(new_prompt);
  return value_char;
}



char * util_scanf_alloc_string(const char * prompt) {
  char input[256];
  printf("%s" , prompt);
  scanf("%256s" , input);
  return util_alloc_string_copy(input);
}



/**
   This function counts the number of lines from the current position
   in the file, to the end of line. The file pointer is repositioned
   at the end of the counting.
*/


int util_count_file_lines(FILE * stream) {
  long int init_pos = ftell(stream);
  int lines = 0;
  bool at_eof = false;
  do {
    int col = util_forward_line(stream , &at_eof);
    if (col > 0) lines++;
  } while (!at_eof);
  fseek(stream , init_pos , SEEK_SET);
  return lines;
}


int util_count_content_file_lines(FILE * stream) {
  int lines       = 0;
  int empty_lines = 0;
  int col         = 0;
  char    c;
  
  do {
    c = fgetc(stream);
    if (EOL_CHAR(c)) {
      if (col == 0)
        empty_lines++;
      else {
        lines       += empty_lines + 1;
        empty_lines  = 0;
      }
      col = 0;
      c = fgetc(stream);
      if (! feof(stream) ) {
        if (!EOL_CHAR(c))
          fseek(stream , -1 , SEEK_CUR);
      }
    } else if (c == EOF)
      lines++;
    else {
      if (c != ' ')
        col++;
    }
  } while (! feof(stream) );
  if (col == 0) 
    /*
      Not counting empty last line.
    */
    lines--;
  return lines;
}


/******************************************************************/


/** 
    buffer_size is _only_ for a return (by reference) of the size of
    the allocation. Can pass in NULL if that size is not interesting.
*/

char * util_fread_alloc_file_content(const char * filename , int * buffer_size) {
  size_t file_size = util_file_size(filename);
  char * buffer = util_calloc(file_size + 1 , sizeof * buffer );
  {
    FILE * stream = util_fopen(filename , "r");
    util_fread( buffer , 1 , file_size , stream , __func__);
    fclose(stream);
  }
  if (buffer_size != NULL) *buffer_size = file_size;
  
  buffer[file_size] = '\0';
  return buffer;
}


/**
   If abort_on_error = true the function will abort if the read/write
   fails (although the write will try the disk_full hack). If
   abort_on_error == false the function will just return false if the
   write fails, in this case the calling scope must do the right
   thing.
*/
  

bool util_copy_stream(FILE *src_stream , FILE *target_stream , int buffer_size , void * buffer , bool abort_on_error) {

  while ( ! feof(src_stream)) {
    int bytes_read;
    int bytes_written;
    bytes_read = fread (buffer , 1 , buffer_size , src_stream);
    
    if (bytes_read < buffer_size && !feof(src_stream)) {
      if (abort_on_error)
        util_abort("%s: error when reading from src_stream - aborting \n",__func__);
      else
        return false;
    }

    if (abort_on_error)
      util_fwrite( buffer , 1 , bytes_read , target_stream , __func__);
    else {
      bytes_written = fwrite(buffer , 1 , bytes_read , target_stream);
      if (bytes_written < bytes_read) 
        return false;
    }
  }
  
  return true;
}


static bool util_copy_file__(const char * src_file , const char * target_file, int buffer_size , void * buffer , bool abort_on_error) {
  if (util_same_file(src_file , target_file)) {
    fprintf(stderr,"%s Warning: trying to copy %s onto itself - nothing done\n",__func__ , src_file);
    return false;
  } else {
    {
      FILE * src_stream      = util_fopen(src_file     , "r");
      FILE * target_stream   = util_fopen(target_file  , "w");
      bool result = util_copy_stream(src_stream , target_stream , buffer_size , buffer , abort_on_error);
        
      fclose(src_stream);
      fclose(target_stream);
      return result;
    }
  }
}



bool util_copy_file(const char * src_file , const char * target_file) {
  const bool abort_on_error = true;
  void * buffer   = NULL;
  size_t buffer_size = util_size_t_max( 32 , util_file_size(src_file) );  /* The copy stream function will hang if buffer size == 0 */
  do {
    buffer = malloc(buffer_size);
    if (buffer == NULL) buffer_size /= 2;
  } while ((buffer == NULL) && (buffer_size > 0));
  
  if (buffer_size == 0)
    util_abort("%s: failed to allocate any memory ?? \n",__func__);
  
  {
    bool result = util_copy_file__(src_file , target_file , buffer_size , buffer , abort_on_error);
    free(buffer);
    return result;
  }
}

void util_move_file(const char * src_file , const char * target_file) {
  if (util_file_exists( src_file )) {
    if (util_copy_file( src_file , target_file))
      remove( src_file );
  }
}


void util_move_file4( const char * src_name , const char * target_name , const char *src_path , const char * target_path) {
  char * src;
  char * target;

  if (src_path != NULL)
    src = util_alloc_filename( src_path , src_name , NULL);
  else
    src = util_alloc_string_copy( src_name );

  if (target_name == NULL)
    target_name = src_name;

  if (target_path == NULL)
    target_path = src_path;
  
  if (target_path != NULL)
    target = util_alloc_filename( target_path , target_name , NULL);
  else
    target = util_alloc_string_copy( target_name );


  util_move_file( src , target );
  
  free( target );
  free( src );
}



/**
   Only the file _content_ is considered - file metadata is ignored.
*/

bool util_files_equal( const char * file1 , const char * file2 ) {
  bool equal = true;
  const int buffer_size = 4096;
  char * buffer1 = util_calloc( buffer_size , sizeof * buffer1 );
  char * buffer2 = util_calloc( buffer_size , sizeof * buffer2 );
  
  FILE * stream1 = util_fopen( file1 , "r" );
  FILE * stream2 = util_fopen( file2 , "r" );

  do {
    int count1 = fread( buffer1 , 1 , buffer_size , stream1 );
    int count2 = fread( buffer2 , 1 , buffer_size , stream2 );

    if (count1 != count2) 
      equal = false;
    else {
      if (memcmp( buffer1 , buffer2 , count1 ) != 0)
        equal = false;
    }

    if (feof(stream1)) {
      if (feof(stream2))
        break;
      else
        equal = false;
    }
  } while (equal);
  fclose( stream1 );
  fclose( stream2 );

  free( buffer1 );
  free( buffer2 );
  return equal;
}


static void util_fclear_region( FILE * stream , long offset , long region_size) {
  fseek( stream , offset , SEEK_SET );
  { 
     int i;
     for ( i=0; i < region_size; i++)
        fputc( 0 , stream );
  }
}


static void util_fmove_block(FILE * stream , long offset , long shift , char * buffer , int buffer_size) {
  fseek( stream , offset , SEEK_SET );
  {
    int bytes_read = fread( buffer , sizeof * buffer , buffer_size , stream );
    fseek( stream , offset + shift , SEEK_SET );
    fwrite( buffer , sizeof * buffer , bytes_read , stream );
  }
}


/**
   This function will modify a file in place by moving the part from
   @offset and to the end of the file @shift bytes. If @shift is
   positive a 'hole' will be created in the file, if @shift is
   negative a part of the file will be overwritten:

     Original        : "ABCDEFGHIJKILMNOPQ"
     fmove( 10 , 5 ) : "ABCDEFGHIJ     KILMNOPQ"   
     fmove( 10 , -5) : "ABCDEKILMNOPQ"

  If offset is positioned at the end of the file a section initialized
  to zero will be appended to the file. If @offset is beyond the end
  of the file the function will return EINVAL.

  For this function to work the file must be opened in read-write mode
  (i.e. r+).  
*/

int util_fmove( FILE * stream , long offset , long shift) {
  long file_size;
  // Determine size of file.
  {
    long init_pos = ftell( stream );
    fseek( stream , 0 , SEEK_END);
    file_size = ftell( stream );
    fseek( stream , init_pos , SEEK_SET );
  }
    
  // Validate offset and shift input values.
  if ((offset > file_size) || (offset < 0))
    return EINVAL;
  
  if (offset + shift < 0)
    return EINVAL;
  
  if (shift != 0) {
    int buffer_size = 1024 * 1024 * 4;  /* 4MB buffer size. */
    char * buffer = util_calloc( buffer_size , sizeof * buffer );
    
    /* Shift > 0: We are opening up a hole in the file. */
    if (shift > 0) {
      long pos = offset;
      while (( pos + buffer_size ) < file_size)
        pos += buffer_size;
      
      while (pos >= offset) {
        util_fmove_block( stream , pos , shift , buffer , buffer_size );
        pos -= buffer_size;
      }
      util_fclear_region( stream , offset , shift );
    } else {
      /* Shift < 0: We are overwriting a part of the file internally. */  
      long pos = offset;
      while (pos <= file_size) {
        util_fmove_block( stream , pos , shift , buffer , buffer_size );
        pos += buffer_size;
      }
      
      // Make sure the file actually shrinks.
      util_ftruncate( stream  , file_size + shift );
    }
    free( buffer );
  }
  return 0; 
}  







/**
   Currently only checks if the entry exists - this will return true
   if path points to directory.
*/
bool util_file_exists(const char *filename) {
  return util_entry_exists( filename );
}



/**
   Checks if there is an entry in the filesystem - i.e.  ordinary
   file, directory , symbolic link, ... with name 'entry'; and returns
   true/false accordingly.
*/

bool util_entry_exists( const char * entry ) {
  struct stat stat_buffer;
  int stat_return = stat(entry, &stat_buffer);
  if (stat_return == 0)
    return true;
  else {
    if (errno == ENOENT)
      return false;
    else {
      util_abort("%s: error checking for entry:%s  %d/%s \n",__func__ , entry , errno , strerror(errno));
      return false;
    }
  }
}

/*****************************************************************/



/**
   The semantics for all the is_xxx functions is follows:

   1. Call stat(). If stat fails with ENOENT the entry does not exist
      at all - return false.

   2. If stat() has succeeded check the type of the entry, and return
      true|false if it is of the wanted type.
      
   3. If stat() fails with error != ENOENT => util_abort().   

*/





bool util_is_directory(const char * path) {
  struct stat stat_buffer;

  if (stat(path , &stat_buffer) == 0)
    return S_ISDIR(stat_buffer.st_mode);
  else if (errno == ENOENT)
    /*Path does not exist at all. */
    return false;
  else {
    util_abort("%s: stat(%s) failed: %s \n",__func__ , path , strerror(errno));
    return false; /* Dummy to shut the compiler warning */
  }
}



bool util_is_file(const char * path) {
  struct stat stat_buffer;

  if (stat(path , &stat_buffer) == 0)
    return S_ISREG(stat_buffer.st_mode);
  else if (errno == ENOENT)
    /*Path does not exist at all. */
    return false;
  else {
    util_abort("%s: stat(%s) failed: %s \n",__func__ , path , strerror(errno));
    return false; /* Dummy to shut the compiler warning */
  }
}



/**
   Will return false if the path does not exist.
*/

#ifdef HAVE_FORK
bool util_is_executable(const char * path) {
  if (util_file_exists(path)) {
    struct stat stat_buffer;
    stat(path , &stat_buffer);
    if (S_ISREG(stat_buffer.st_mode))
      return (stat_buffer.st_mode & S_IXUSR);
    else
      return false; /* It is not a file. */
  } else  /* Entry does not exist - return false. */
    return false; 
}


/* 
   Will not differtiate between files and directories.
*/
bool util_entry_readable( const char * entry ) {
  struct stat buffer;
  if (stat( entry , &buffer ) == 0)
    return buffer.st_mode & S_IRUSR;
  else
    return false;  /* If stat failed - typically not existing entry - we return false. */
}


bool util_file_readable( const char * file ) {
  if (util_entry_readable( file ) && util_is_file( file ))
    return true;
  else
    return false;
}

bool util_entry_writable( const char * entry ) {
  struct stat buffer;
  if (stat( entry , &buffer ) == 0)
    return buffer.st_mode & S_IWUSR;
  else
    return false;  /* If stat failed - typically not existing entry - we return false. */
}



#else
  // Windows: executable status based purely on extension ....

bool util_is_executable(const char * path) {
  char * ext;
  util_alloc_file_components( path , NULL , NULL , &ext);
  if (ext != NULL)
    if (strcmp(ext , "exe") == 0)
      return true;
  
  return false;
}

/* If it exists on windows it is readable ... */
bool util_entry_readable( const char * entry ) {
  struct stat buffer;
  if (stat( entry , &buffer ) == 0)
    return true;
  else
    return false;  /* If stat failed - typically not existing entry - we return false. */
}

/* If it exists on windows it is readable ... */
bool util_entry_writable( const char * entry ) {
  struct stat buffer;
  if (stat( entry , &buffer ) == 0)
    return true;
  else
    return false;  /* If stat failed - typically not existing entry - we return false. */
}



#endif 



static int util_get_path_length(const char * file) {
  if (util_is_directory(file)) 
    return strlen(file);
  else {
    const char * last_slash = strrchr(file , UTIL_PATH_SEP_CHAR);
    if (last_slash == NULL)
      return 0;
    else 
      return last_slash - file;
  }
}



static int util_get_base_length(const char * file) {
  int path_length   = util_get_path_length(file);
  const char * base_start;
  const char * last_point;

  if (path_length == strlen(file))
    return 0;
  else if (path_length == 0)
    base_start = file;
  else 
    base_start = &file[path_length + 1];
  
  last_point  = strrchr(base_start , '.');
  if (last_point == NULL)
    return strlen(base_start);
  else
    return last_point - base_start;

}



/**
   This function splits a filename into three parts:

    1. A leading path.
    2. A base name.
    3. An extension.

   In the calling scope you should pass in references to pointers to
   char for the fields, you are interested in:

   Example:
   --------

   char * path;
   char * base;
   char * ext;

   util_alloc_file_components("/path/to/some/file.txt" , &path , &base , &ext);
   util_alloc_file_components("/path/to/some/file.txt" , &path , &base , NULL); 

   In the second example we were not interested in the extension, and
   just passed in NULL. Before use in the calling scope it is
   essential to check the values of base, path and ext:

   util_alloc_file_components("/path/to/some/file" , &path , &base , &ext);
   if (ext != NULL)
      printf("File: has extension: %s \n",ext);
   else
      printf("File does *not* have an extension \n");

   The memory allocated in util_alloc_file_components must be freed by
   the calling unit. 

   Observe the following: 

    * It is easy to be fooled by the optional existence of an extension
      (badly desgined API).

    * The function is **NOT** based purely on string parsing, but also
      on checking stat() output to check if the argument you send in
      is an existing directory (that is done through the
      util_get_path_length() function).


      Ex1: input is an existing directory:
      ------------------------------------
      util_alloc_file_components("/some/existing/path" , &path , &base , &ext)

        path -> "/some/existing/path"
        base -> NULL
        ext  -> NULL
        
        

      Ex2: input is NOT an existing directory:
      ------------------------------------
      util_alloc_file_components("/some/random/not_existing/path" , &path , &base , &ext)
      
      path -> "/some/random/not_existing"
        base -> "path"
        ext  -> NULL
        
*/

void util_alloc_file_components(const char * file, char **_path , char **_basename , char **_extension) {
  char *path      = NULL;
  char *basename  = NULL;
  char *extension = NULL;
  
  int path_length = util_get_path_length(file);
  int base_length = util_get_base_length(file);
  int ext_length ;
  int slash_length = 1;
  
  if (path_length > 0) 
    path = util_alloc_substring_copy(file , 0 , path_length);
  else
    slash_length = 0;


  if (base_length > 0)
    basename = util_alloc_substring_copy(file , path_length + slash_length , base_length);

  
  ext_length = strlen(file) - (path_length + base_length + 1);
  if (ext_length > 0)
    extension = util_alloc_substring_copy(file , (path_length + slash_length + base_length + 1) , ext_length);

  if (_extension != NULL) 
    *_extension = extension;
  else 
    if (extension != NULL) free(extension);
  

  if (_basename != NULL) 
    *_basename = basename;
  else 
    if (basename != NULL) free(basename);
  
  
  if (_path != NULL) 
    *_path = path;
  else 
    if (path != NULL) free(path);
  

}






size_t util_file_size(const char *file) {
  struct stat buffer;
  int fildes;
  
  fildes = open(file , O_RDONLY);
  if (fildes == -1) 
    util_abort("%s: failed to open:%s - %s \n",__func__ , file , strerror(errno));
  
  fstat(fildes, &buffer);
  close(fildes);
  
  return buffer.st_size;
}









void util_ftruncate(FILE * stream , long size) {
  int fd = fileno( stream );
#ifdef HAVE_FTRUNCATE
  ftruncate( fd , size );
#else
  _chsize( fd , size );
#endif
}





/*
  The windows stat structure has the inode element, but it is not
  set. Actually - this is a property of the filesystem, and not the
  operating system - this check is probably broken on two levels:
  
   1. One should really check the filesystem involved - whether it
      supports inodes.
      
   2. The code below will compile on windows, but for a windows
      filesystem it will yield rubbish.
*/

bool util_same_file(const char * file1 , const char * file2) {
  struct stat buffer1 , buffer2;
  int stat1,stat2;

  stat1 = stat(file1, &buffer1);   // In the case of symlinks the stat call will stat the target file and not the link.
  stat2 = stat(file2, &buffer2);
  
  if ((stat1 == 0) && (stat1 == stat2)) {
    if (buffer1.st_ino == buffer2.st_ino) 
      return true;
    else
      return false;
  } else
    return false;  // Files which do not exist are no equal!
}







void util_unlink_existing(const char *filename) {
  if (util_file_exists(filename))
    remove(filename);
}


bool util_fmt_bit8_stream(FILE * stream ) {
  const int    min_read      = 256; /* Critically small */
  const double bit8set_limit = 0.00001;
  const int    buffer_size   = 131072;
  long int start_pos         = ftell(stream);
  bool fmt_file;
  {
    double bit8set_fraction;
    int N_bit8set = 0;
    int elm_read,i;
    char *buffer = util_calloc(buffer_size , sizeof * buffer );

    elm_read = fread(buffer , 1 , buffer_size , stream);
    if (elm_read < min_read) 
      util_abort("%s: file is too small to automatically determine formatted/unformatted status \n",__func__);
    
    for (i=0; i < elm_read; i++)
      N_bit8set += (buffer[i] & (1 << 7)) >> 7;
    
    
    free(buffer);
  
    bit8set_fraction = 1.0 * N_bit8set / elm_read;
    if (bit8set_fraction < bit8set_limit) 
      fmt_file =  true;
    else 
      fmt_file = false;
  }
  fseek(stream , start_pos , SEEK_SET);
  return fmt_file;
}  



bool util_fmt_bit8(const char *filename ) {
  FILE *stream;
  bool fmt_file = true;

  if (util_file_exists(filename)) {
    stream   = fopen(filename , "r");
    fmt_file = util_fmt_bit8_stream(stream);
    fclose(stream);
  } else 
    util_abort("%s: could not find file: %s - aborting \n",__func__ , filename);

  return fmt_file;
}



/*
  time_t        st_atime;    time of last access 
  time_t        st_mtime;    time of last modification 
  time_t        st_ctime;    time of last status change 
*/

/*
  The returned value is the difference in file mtime from the file2 to
  file1 (what a mess). I.e. if file1 is newer than file2 the returned
  value will be positive.  
*/




double util_file_difftime(const char *file1 , const char *file2) {
  struct stat b1, b2;
  int f1,f2;
  time_t t1,t2;

  f1 = open(file1 , O_RDONLY);
  fstat(f1, &b1);
  t1 = b1.st_mtime;
  close(f1);

  f2 = open(file2 , O_RDONLY);
  fstat(f2, &b2);
  t2 = b2.st_mtime;
  close(f2);

  return difftime(t1 , t2);
}


time_t util_file_mtime(const char * file) {
  time_t mtime = -1;
  int fd = open( file , O_RDONLY);
  if (fd != -1) {
    struct stat f_stat;
    fstat(fd , &f_stat );
    mtime = f_stat.st_mtime;
    close( fd );
  } 
  return mtime;
}




/**
   Will check if the st_mtime (i.e. last modification) of the file is
   after the time given by @t0.  
*/

bool util_file_newer( const char * file , time_t t0) {
  time_t mtime = util_file_mtime( file );
  if (difftime(mtime , t0) > 0)
    return true;
  else
    return false;
}

/**
   Will check if the st_mtime (i.e. last modification) of the file is
   before the time given by @t0.  
*/


bool util_file_older( const char * file , time_t t0) {
  time_t mtime = util_file_mtime( file );
  if (difftime(mtime , t0) < 0)
    return true;
  else
    return false;
}


bool util_before( time_t t , time_t limit) {
  if (difftime(limit , t) > 0)
    return true;
  else
    return false;
}


bool util_after( time_t t , time_t limit) {
  if (difftime(limit , t) < 0)
    return true;
  else
    return false;
}



/** 
    This function will return a pointer to the newest of the two
    files. If one of the files does not exist - the other is
    returned. If none of the files exist - NULL is returned.
*/

char * util_newest_file(const char *file1 , const char *file2) {
  if (util_file_exists(file1)) {
    if (util_file_exists(file2)) {
      /* Actual comparison of two existing files. */
      if (util_file_difftime(file1 , file2) < 0)
        return (char *) file1;
      else
        return (char *) file2;
    } else
      return (char *)file1;   /* Only file1 exists. */
  } else {
    if (util_file_exists(file2))
      return (char *) file2; /* Only file2 exists. */
    else
      return NULL;   /* None of the files exist. */
  }
}


bool util_file_update_required(const char *src_file , const char *target_file) {
  if (util_file_difftime(src_file , target_file) < 0)
    return true;
  else
    return false;
}




static void __util_set_timevalues(time_t t , int * sec , int * min , int * hour , int * mday , int * month , int * year) {
  struct tm ts;

  util_localtime(&t , &ts);
  if (sec   != NULL) *sec   = ts.tm_sec;
  if (min   != NULL) *min   = ts.tm_min;
  if (hour  != NULL) *hour  = ts.tm_hour;
  if (mday  != NULL) *mday  = ts.tm_mday;
  if (month != NULL) *month = ts.tm_mon  + 1;
  if (year  != NULL) *year  = ts.tm_year + 1900;
}


/*
  This function takes a time_t instance as input, and 
  returns the the time broken down in sec:min:hour  mday:month:year.

  The return values are by pointers - you can pass in NULL to any of
  the fields.
*/
void util_set_datetime_values(time_t t , int * sec , int * min , int * hour , int * mday , int * month , int * year) {
  __util_set_timevalues(t , sec , min , hour , mday , month , year);
}


void util_set_date_values(time_t t , int * mday , int * month , int * year) {
  __util_set_timevalues(t , NULL , NULL , NULL , mday , month , year);
}


bool util_is_first_day_in_month( time_t t) {
  int mday;
  __util_set_timevalues(t , NULL , NULL , NULL , &mday ,NULL, NULL);
  if (mday == 1)
    return true;
  else
    return false;
}


/**
   If the parsing fails the time_t pointer is set to -1;
*/
bool util_sscanf_date(const char * date_token , time_t * t) {
  int day   , month , year;
  char sep1 , sep2;
  
  if (sscanf(date_token , "%d%c%d%c%d" , &day , &sep1 , &month , &sep2 , &year) == 5) {
    *t = util_make_date(day , month , year );  
    return true;
  } else {
    *t = -1;
    return false;
  }
}


bool util_fscanf_date(FILE *stream , time_t *t)  {
  int init_pos = ftell(stream);
  char * date_token = util_fscanf_alloc_token(stream);
  bool return_value = util_sscanf_date(date_token , t);
  if (!return_value) fseek(stream , init_pos , SEEK_SET);
  free(date_token);
  return return_value;
}

/* 
   The date format is HARD assumed to be

   dd/mm/yyyy

   Where mm is [1..12]
   yyyy ~2000

*/


void util_fprintf_datetime(time_t t , FILE * stream) {
  int sec,min,hour;
  int mday,year,month;
  
  util_set_datetime_values(t , &sec , &min , &hour , &mday , &month , &year);
  fprintf(stream , "%02d/%02d/%4d  %02d:%02d:%02d", mday,month,year,hour,min,sec);
}


void util_fprintf_date(time_t t , FILE * stream) {
  int mday,year,month;
  
  util_set_datetime_values(t , NULL , NULL , NULL , &mday , &month , &year);
  fprintf(stream , "%02d/%02d/%4d", mday,month,year);
}


char * util_alloc_date_string( time_t t ) {
  int mday,year,month;
  
  util_set_datetime_values(t , NULL , NULL , NULL , &mday , &month , &year);
  return util_alloc_sprintf("%02d/%02d/%4d", mday,month,year);
}

char * util_alloc_date_stamp( ) {
  time_t now = time( NULL );
  return util_alloc_date_string( now );
}


/* 
   This function takes a pointer to a time_t instance, and shifts the
   value days forward. Observe the calls to localtime_r() which give
   rise to +/- one extra hour of adjustment if we have crossed exactly
   one daylight savings border.

   This code produced erroneus results when compiled with -pg for
   profiling. (Maybe because the ts variable was not properly
   initialized when reading off the first isdst setting??)
*/

void util_inplace_forward_days(time_t * t , double days) {
  struct tm ts;
  int isdst;
  
  util_localtime(t , &ts);
  isdst = ts.tm_isdst;
  (*t) += ( time_t ) (days * 3600 * 24);
  util_localtime(t , &ts);
  (*t) += 3600 * (isdst - ts.tm_isdst);  /* Extra adjustment of +/- one hour if we have crossed exactly one daylight savings border. */
}


/**
   This function computes the difference in time between times time1
   and time0: time1 - time0. The return value is the difference in
   seconds (straight difftime output). Observe that the ordering of
   time_t arguments is switched with respect to the difftime
   arguments.
   
   In addition the difference can be broken down in days, hours,
   minutes and seconds if the appropriate pointers are passed in.
*/

   
double util_difftime(time_t start_time , time_t end_time , int * _days , int * _hours , int * _minutes , int *_seconds) {
  int sec_min  = 60;
  int sec_hour = 3600;
  int sec_day  = 24 * 3600;
  double dt = difftime(end_time , start_time);
  double dt0 = dt;
  int days , hours, minutes , seconds;

  days = (int) floor(dt / sec_day );
  dt  -= days * sec_day;
  
  hours = (int) floor(dt / sec_hour);
  dt   -= hours * sec_hour;
  
  minutes = (int) floor(dt / sec_min);
  dt     -= minutes * sec_min;

  seconds = (int) dt;

  if (_seconds != NULL) *_seconds = seconds;
  if (_minutes != NULL) *_minutes = minutes;
  if (_hours   != NULL) *_hours   = hours;
  if (_days    != NULL) *_days    = days;
  
  return dt0;
}



/* Is this dst safe ??? */
double util_difftime_days(time_t start_time , time_t end_time) {
  double dt = difftime(end_time , start_time);
  return dt / (24 * 3600);
}


double util_difftime_seconds( time_t start_time , time_t end_time) {
  double dt = difftime(end_time , start_time);
  return dt;
}


/*
  Observe that this routine does the following transform before calling mktime:

  1. month -> month - 1;
  2. year  -> year  - 1900;

  Then it is on the format which mktime expects.

*/

time_t util_make_datetime(int sec, int min, int hour , int mday , int month , int year) {
  struct tm ts;
  ts.tm_sec    = sec;
  ts.tm_min    = min;
  ts.tm_hour   = hour;
  ts.tm_mday   = mday;
  ts.tm_mon    = month - 1;
  ts.tm_year   = year  - 1900;
  ts.tm_isdst  = -1;    /* Negative value means mktime tries to determine automagically whether Daylight Saving Time is in effect. */
  {
    time_t t = mktime( &ts );
    if (t == -1) 
      util_abort("%s: failed to make a time_t instance of %02d/%02d/%4d  %02d:%02d:%02d - aborting \n",__func__ , mday,month,year,hour,min,sec);
    
    return t;
  }
}



time_t util_make_date(int mday , int month , int year) {
  return util_make_datetime(0 , 0 , 0 , mday , month , year);
}


time_t util_make_pure_date(time_t t) {
  int day,month,year;
  util_set_date_values( t , &day , &month , &year);
  return util_make_date( day , month , year );
}




/*****************************************************************/

void util_set_strip_copy(char * copy , const char *src) {
  const char null_char  = '\0';
  const char space_char = ' ';
  int  src_index   = 0;
  int target_index = 0;
  while (src[src_index] == space_char)
    src_index++;

  while (src[src_index] != null_char && src[src_index] != space_char) {
    copy[target_index] = src[src_index];
    src_index++;
    target_index++;
  }
  copy[target_index] = null_char;
}


/**
   The function will allocate a new copy of src where leading and
   trailing whitespace has been stripped off. If the source string is
   all blanks a string of length one - only containing \0 is returned,
   i.e. not NULL.

   If src is NULL the function will return NULL. The incoming source
   string is not modified, see the function util_realloc_strip_copy()
   for a similar function implementing realloc() semantics.
*/


char * util_alloc_strip_copy(const char *src) {
  char * target;
  int strip_length = 0;
  int end_index   = strlen(src) - 1;
  while (end_index >= 0 && src[end_index] == ' ')
    end_index--;

  if (end_index >= 0) {

    int start_index = 0;
    while (src[start_index] == ' ')
      start_index++;
    strip_length = end_index - start_index + 1;
    target = util_calloc(strip_length + 1 , sizeof * target );
    memcpy(target , &src[start_index] , strip_length);
  } else 
    /* A blank string */
    target = util_calloc(strip_length + 1 , sizeof * target );

  target[strip_length] = '\0';
  return target;
}



char * util_realloc_strip_copy(char *src) {
  if (src == NULL)
    return NULL;
  else {
    char * strip_copy = util_alloc_strip_copy(src);
    free(src);
    return strip_copy;
  }
}


char ** util_alloc_stringlist_copy(const char **src, int len) {
  if (src != NULL) {
    int i;
    char ** copy = util_calloc(len , sizeof * copy );
    for (i=0; i < len; i++)
      copy[i] = util_alloc_string_copy(src[i]);
    return copy;
  } else 
    return NULL;
}


/**
   This function reallocates the stringlist pointer, making room for
   one more char *, this newly allocated slot is then set to point to
   (a copy of) the new string. The newly reallocated char ** instance
   is the return value from this function.

   Example:
   --------
   char ** stringlist  = (char *[2]) {"One" , "Two"};
   char  * three_string = "Three";
   
   stringlist = util_stringlist_append_copy(stringlist , 2 , three_string);

   This function does allocate memory - but does not have *alloc* in
   the name - hmmmm....??
*/




char ** util_stringlist_append_copy(char ** string_list, int size , const char * append_string) {
  return util_stringlist_append_ref(string_list , size , util_alloc_string_copy(append_string));
}


/**
   This is nearly the same as util_stringlist_append_copy(), but for
   this case only a refernce to the new string is appended.

   Slightly more dangerous to use ...
*/

char ** util_stringlist_append_ref(char ** string_list, int size , const char * append_string) {
  string_list = util_realloc(string_list , (size + 1) * sizeof * string_list );
  string_list[size] = (char *) append_string;
  return string_list;
}



char * util_alloc_string_copy(const char *src ) {
  if (src != NULL) {
    int byte_size = (strlen(src) + 1) * sizeof * src;
    char * copy   = util_calloc( byte_size , sizeof * copy );
    memcpy( copy , src , byte_size );
    return copy;
  } else 
    return NULL;
}



char * util_realloc_string_copy(char * old_string , const char *src ) {
  if (src != NULL) {
    char *copy = util_realloc(old_string , (strlen(src) + 1) * sizeof *copy );
    strcpy(copy , src);
    return copy;
  } else {
    if (old_string != NULL)
      free(old_string);
    return NULL;
  }
}


char * util_realloc_substring_copy(char * old_string , const char *src , int len) {
  if (src != NULL) {
    int str_len;
    char *copy;
    if (strlen(src) < len)
      str_len = strlen(src);
    else
      str_len = len;

    copy = realloc(old_string , (str_len + 1) * sizeof *copy);
    strncpy(copy , src , str_len);
    copy[str_len] = '\0';

    return copy;
  } else 
    return NULL;
}


/**
   This function check that a pointer is different from NULL, and
   frees the memory if that is the case. 
*/
 

void util_safe_free(void *ptr) { 
   if (ptr != NULL) free(ptr); 
}




/**
   This function checks whether a string matches a pattern with
   wildcard(s). The pattern can consist of plain string parts (which
   must match verbatim), and an arbitrary number of '*' which will
   match an arbitrary number (including zero) of arbitrary characters.
   
   Examples:
   ---------

   util_string_match("Bjarne" , "Bjarne")    ==> True

   util_string_match("Bjarne" , "jarn")      ==> False   

   util_string_match("Bjarne" , "*jarn*")    ==> True

   util_string_match("Bjarne" , "B*e")       ==> True
   
   util_string_match("Bjarne" , "B*n")       ==> False

   util_string_match("Bjarne" , "*")         ==> True

   util_string_match("Bjarne" , "B***jarne") ==> True

   util_string_match("Bjarne" , "B*r*e")     ==> True

*/



bool util_string_match(const char * string , const char * pattern) {
  const   char    wildcard    = '*';
  const   char   *wildcard_st = "*";

  if (strcmp(wildcard_st , pattern) == 0) 
    return true;
  else {
    bool    match = true;
    char ** sub_pattern;
    int     num_patterns;
    char *  string_ptr;
    util_split_string( pattern , wildcard_st , &num_patterns , &sub_pattern );
    
    if (pattern[0] == '*')
      string_ptr = strstr(string , sub_pattern[0]);
    else
      string_ptr = (strncmp(string , sub_pattern[0] , strlen(sub_pattern[0])) == 0) ? (char * ) string : NULL;
    
    if (string_ptr != NULL) {
      /* Inital part matched */
      int i;
          string_ptr += strlen( sub_pattern[0] );
      for (i=1; i < num_patterns; i++) {
        char * match_ptr = strstr(string_ptr , sub_pattern[i]);
        if (match_ptr != NULL) 
          string_ptr = match_ptr + strlen( sub_pattern[i] );
        else {
          match = false;
          break;
        }
      }
      
      /* 
         We have exhausted the complete pattern - matching all the way.
         Does it match at the end?
      */
      if (match) {
        if (strlen(string_ptr) > 0) {
          /* 
             There is more left at the end of the string; if the pattern
             ends with '*' that is OK, otherwise the match result is
             FALSE.
          */
          if (pattern[(strlen(pattern) - 1)] != wildcard)
            match = false;
        }
      }
      
    } else 
      match = false;
    
    util_free_stringlist( sub_pattern , num_patterns);
    return match;
  }
}

/**
   Will check the input string 's' and return true if it contains
   wildcard characters (i.e. '*'), and false otherwise.
*/

bool util_string_has_wildcard( const char * s) {
  const char wildcard = '*';
  if (strchr(s , wildcard) != NULL)
    return true;
  else
    return false;
}



void util_free_stringlist(char **list , int N) {
  int i;
  if (list != NULL) {
    for (i=0; i < N; i++) {
      util_safe_free( list[i] );
    }
    free(list);
  }
}


/**
   Will free a list of strings where the last element is NULL. Will
   go completely canacas if the list is not NULL terminated.
*/

void util_free_NULL_terminated_stringlist(char ** string_list) {
  if (string_list != NULL) {
    int i = 0;
    while (true) {
      if (string_list[i] == NULL)
        break;
      else
        free( string_list[i] );
      i++;
    }
    free( string_list );
  }
}




/**
   This function will reallocate the string s1 to become the sum of s1
   and s2. If s1 == NULL it will just return a copy of s2. 

   Observe that due to the use realloc() the s1 input argument MUST BE
   the return value from a malloc() call; this is not intuitive and
   the function should be discontinued.
*/

char * util_strcat_realloc(char *s1 , const char * s2) {
  if (s1 == NULL) 
    s1 = util_alloc_string_copy(s2);
  else {
    if (s2 != NULL) {
      int new_length = strlen(s1) + strlen(s2) + 1;
      s1 = util_realloc( s1 , new_length );
      strcat(s1 , s2);
    } 
  }
  return s1;
}


char * util_alloc_string_sum(const char ** string_list , int N) {
  int i , len;
  char * buffer;
  len = 0;
  for (i=0; i < N; i++) {
    if (string_list[i] != NULL)
      len += strlen(string_list[i]);
  }
  buffer = util_calloc(len + 1 , sizeof * buffer );
  buffer[0] = '\0';
  for (i=0; i < N; i++) {
    if (string_list[i] != NULL)
      strcat(buffer , string_list[i]);
  }
  return buffer;
}


/*****************************************************************/


/**
  Allocates a new string consisting of all the elements in item_list,
  joined together with sep as separator. Elements in item_list can be
  NULL, this will be replaced with the empty string.
*/


char * util_alloc_joined_string(const char ** item_list , int len , const char * sep) {
  if (len <= 0)
    return NULL;
  else {
    char * joined_string;
    int sep_length   = strlen(sep);
    int total_length = 0;
    int eff_len = 0;
    int i;
    for (i=0; i < len; i++) 
      if (item_list[i] != NULL) {
        total_length += strlen(item_list[i]);
        eff_len++;
      }

    if (eff_len > 0) {
      total_length += (eff_len - 1) * sep_length + 1;
      joined_string = util_calloc(total_length , sizeof * joined_string );
      joined_string[0] = '\0';
      for (i=0; i < len; i++) {
        if (item_list[i] != NULL) {
          if (i > 0)
            strcat(joined_string , sep);
          strcat(joined_string , item_list[i]);
        }
      }
      return joined_string;
    } else
      return NULL;
  }
}


/**
  New string is allocated by joining the elements in item_list, with
  "\n" character as separator; an extra "\n" is also added at the end
  of the list.
*/
char * util_alloc_multiline_string(const char ** item_list , int len) {
  char * multiline_string = util_alloc_joined_string(item_list , len , UTIL_NEWLINE_STRING);
  multiline_string = util_realloc(multiline_string , (strlen(multiline_string) + strlen(UTIL_NEWLINE_STRING) + 1) * sizeof * multiline_string );
  strcat(multiline_string , UTIL_NEWLINE_STRING);
  return multiline_string;
}


/**
   sep_set = string with various characters, i.e. " \t" to split on.
*/

void util_split_string(const char *line , const char *sep_set, int *_tokens, char ***_token_list) {
  int offset;
  int tokens , token , token_length;
  char **token_list;

  offset = strspn(line , sep_set); 
  tokens = 0;
  do {
    /*
      if (line[offset] == '\"') {
      seek for terminating ".
      }
    */
    token_length = strcspn(&line[offset] , sep_set);
    if (token_length > 0)
      tokens++;
    
    offset += token_length;
    offset += strspn(&line[offset] , sep_set);
  } while (line[offset] != '\0');

  if (tokens > 0) {
    token_list = util_calloc(tokens , sizeof * token_list );
    offset = strspn(line , sep_set);
    token  = 0;
    do {
      token_length = strcspn(&line[offset] , sep_set);
      if (token_length > 0) {
        token_list[token] = util_alloc_substring_copy(line , offset , token_length);
        token++;
      } else
        token_list[token] = NULL;
      
      offset += token_length;
      offset += strspn(&line[offset] , sep_set);
    } while (line[offset] != '\0');
  } else
    token_list = NULL;
  
  *_tokens     = tokens;
  *_token_list = token_list;
}


/**
   This function will split the input string in two parts, it will
   split on occurence of one or several of the characters in
   sep_set. 


   o If split_on_first is true it will split on the first occurence of
     split_set, and otherwise it will split on the last:

       util_binary_split_string("A:B:C:D , ":" , true  , ) => "A"     & "B:C:D"
       util_binary_split_string("A:B:C:D , ":" , false , ) => "A:B:C" & "D"


   o Characters in the split_set at the front and back are discarded
     _BEFORE_ the actual splitting process.

       util_binary_split_string(":A:B:C:D:" , ":" , true , )   => "A"     & "B:C:D"
       util_binary_split_string(":A:B:C:D:" , ":" , false , )  => "A:B:C" & "D"


   o If no split is found the whole content is in first_part, and
     second_part is NULL. If the input string == NULL, both return
     strings will be NULL. Observe that because leading split
     characters are removed before the splitting starts:

        util_binary_split_string(":ABCD" , ":" , true , )   => "ABCD" & NULL
        
*/


void util_binary_split_string(const char * __src , const char * sep_set, bool split_on_first , char ** __first_part , char ** __second_part) {
  char * first_part = NULL;
  char * second_part = NULL;
  char * src;

  if (__src != NULL) {
    int offset = 0;
    int len;
    /* 1: Remove leading split characters. */
    while ((offset < strlen(__src)) && (strchr(sep_set , __src[offset]) != NULL))
      offset++;
    len = strlen( __src ) - offset;
    if (len > 0) {
      int tail_pos = strlen( __src ) - 1;
      /* 2: Remove trailing split characters. */
      while (strchr(sep_set , __src[tail_pos]) != NULL) 
        tail_pos--;
      len = 1 + tail_pos - offset;
      
      src = util_alloc_substring_copy(__src , offset , len);
    } else
      src = NULL;

    /* 
       OK - we have removed all leading (or trailing) separators, and we have
       a valid string which we can continue with.
    */
    if (src != NULL) {
      int pos;
      int start_pos , delta , end_pos;
      if (split_on_first) {
        start_pos = 0;
        delta     = 1;
        end_pos   = strlen(src);
      } else {
        start_pos = strlen(src) - 1;
        delta     = -1;
        end_pos   = -1;
      }

      pos = start_pos;
      while ((pos != end_pos) && (strchr(sep_set , src[pos]) == NULL)) 
        pos += delta;
      /* 
         OK - now we have either iterated through the whole string - or
         we hav found a character in the sep_set. 
      */
      if (pos == end_pos) {
        /* There was no split. */
        first_part = util_alloc_string_copy( src );
        second_part   = NULL;
      } else {
        int sep_start = 0;
        int sep_end   = 0;
        if (split_on_first)
          sep_start = pos;
        else
          sep_end = pos;
        /* Iterate through the separation string - can be e.g. many " " */
        while ((pos != end_pos) && (strchr(sep_set , src[pos]) != NULL))
          pos += delta;

        if (split_on_first) {
          sep_end = pos;
          first_part = util_alloc_substring_copy(src , 0 , sep_start);
          
          if (sep_end == end_pos)
            second_part = NULL;
          else
            second_part = util_alloc_string_copy( &src[sep_end] );
        } else {
          sep_start = pos;
          if (sep_start == end_pos) {
            // ":String" => (NULL , "String")
            first_part = NULL;
            second_part = util_alloc_string_copy( &src[sep_end+1] );
          } else {
            first_part  = util_alloc_substring_copy( src , 0 , sep_start + 1);
            second_part = util_alloc_string_copy( &src[sep_end + 1]);
          }
        }
      }
      free(src);
    }
  }
  *__first_part  = first_part;
  *__second_part = second_part;
}


void util_binary_split_string_from_max_length(const char * __src , const char * sep_set, int max_length , char ** __first_part , char ** __second_part) {
  char * first_part = NULL;
  char * second_part = NULL;
  if (__src != NULL) {
    char * src;
    int pos;
    /* Removing leading separators. */
    pos = 0;
    while ((pos < strlen(__src)) && (strchr(sep_set , __src[pos]) != NULL))
      pos += 1;
    if (pos == strlen(__src))  /* The string consisted ONLY of separators. */
      src = NULL;
    else
      src = util_alloc_string_copy(&__src[pos]);
    
    /*Remove trailing separators. */
    pos = strlen(__src) - 1;
    while ((pos >= 0) && (strchr(sep_set , __src[pos]) != NULL))
      pos -= 1;
    if (pos < 0)
      src = NULL;
    else
      src = util_alloc_substring_copy(__src , 0 , pos + 1);
    
    
    /* 
       OK - we have removed all leading (or trailing) separators, and we have
       a valid string which we can continue with.
    */
    if (src != NULL) {
      int pos;
      int start_pos , delta , end_pos;
      start_pos = max_length;
      delta     = -1;
      end_pos   = -1;
      pos = start_pos;
      while ((pos != end_pos) && (strchr(sep_set , src[pos]) == NULL)) 
        pos += delta;
      /* 
         OK - now we have either iterated through the whole string - or
         we hav found a character in the sep_set. 
      */
      if (pos == end_pos) {
        /* There was no split. */
        first_part = util_alloc_string_copy( src );
        second_part   = NULL;
      } else {
        int sep_start = 0;
        int sep_end   = 0;
        sep_end = pos;
        /* Iterate through the separation string - can be e.g. many " " */
        while ((pos != end_pos) && (strchr(sep_set , src[pos]) != NULL))
          pos += delta;
        
        
        sep_start = pos;
        if (sep_start == end_pos) {
          // ":String" => (NULL , "String")
          first_part = NULL;
          second_part = util_alloc_string_copy( &src[sep_end+1] );
        } else {
          first_part  = util_alloc_substring_copy( src , 0 , sep_start + 1);
          second_part = util_alloc_string_copy( &src[sep_end + 1]);
        }
      }
      free(src);
    }
  }
  *__first_part  = first_part;
  *__second_part = second_part;
}



/**
   The function will, in-place, update all occurencese: expr->subs.
   The return value is the number of substitutions which have been
   performed. buffer must be \0 terminated.
*/


int static util_string_replace_inplace__(char ** _buffer , const char * expr , const char * subs) {
  char * buffer            = *_buffer;
  int    buffer_size       = strlen( buffer ) + 1;   /* The variable buffer_size is the TOTAL size - including the terminating \0. */
  int len_expr             = strlen( expr );
  int len_subs             = strlen( subs );
  int    size              = strlen(buffer);
  int    offset            = 0;     
  int    match_count       = 0;

  char  * match = NULL;
  do {
    match = strstr(&buffer[offset] ,  expr);
    
    if (match != NULL) {
      /* 
         Can not use pointer arithmetic here - because the underlying
         buffer pointer might be realloced.
      */
      {
        int    start_offset  = match             - buffer;
        int    end_offset    = match + len_expr  - buffer;
        int    target_offset = match + len_subs - buffer;
        int    new_size      = size  + len_subs - len_expr;
        if (new_size >= (buffer_size - 1)) {
          buffer_size += buffer_size + 2*len_subs;
          buffer = util_realloc( buffer , buffer_size );
        }
        {
          char * target    = &buffer[target_offset];
          char * match_end = &buffer[end_offset];
          memmove(target , match_end , 1 + size - end_offset);
        }
      
        memcpy(&buffer[start_offset] , subs , len_subs);
        offset = start_offset + len_subs;
        size   = new_size;
        match_count++;
      }
    }
  } while (match != NULL && offset < strlen(buffer));
    
    
  *_buffer      = buffer;
  return match_count;
}



int util_string_replace_inplace(char ** _buffer , const char * expr , const char * subs) {
  return util_string_replace_inplace__(_buffer , expr , subs );
}




/**
  This allocates a copy of buff_org where occurences of the string expr are replaced with subs.
*/
char * util_string_replace_alloc(const char * buff_org, const char * expr, const char * subs)
{
  int buffer_size   = strlen(buff_org) * 2;
  char * new_buffer = util_calloc(buffer_size ,  sizeof * new_buffer );
  memcpy(new_buffer , buff_org , strlen(buff_org) + 1);
  util_string_replace_inplace__( &new_buffer , expr , subs);
  
  {
    int size = strlen(new_buffer);
    new_buffer = util_realloc(new_buffer, (size + 1) * sizeof * new_buffer);
  }

  return new_buffer;
}



/**
   This allocates a copy of buff_org where occurences of expr[i] are replaced with subs[i] for i=1,..,num_expr.
*/
char * util_string_replacen_alloc(const char * buff_org, int num_expr, const char ** expr, const char ** subs)
{
  int buffer_size   = strlen(buff_org) * 2;
  char * new_buffer = util_calloc(buffer_size , sizeof * new_buffer );
  memcpy(new_buffer , buff_org , strlen(buff_org) + 1);
  {
          int i;
  for( i=0; i<num_expr; i++)
    util_string_replace_inplace__( &new_buffer , expr[i] , subs[i]);
  }
  
  {
          int size = strlen(new_buffer);
          new_buffer = util_realloc(new_buffer, (size + 1) * sizeof * new_buffer);
  }
  
  return new_buffer;
}



/**
  This will alloc a copy of buff_org were char's in the last strings are removed.
*/
char * util_string_strip_chars_alloc(const char * buff_org, const char * chars)
{
  int len_org = strlen(buff_org);
  int pos_org = 0;
  int pos_new = 0;

  char * buff_new = util_calloc( (len_org +1) ,  sizeof * buff_new);

  while(pos_org < len_org)
  {
    int pos_off = strcspn(buff_org + pos_org, chars);
    if(pos_off > 0)
    {
      memmove(buff_new + pos_new, buff_org + pos_org, pos_off * sizeof * buff_new);  
      pos_org += pos_off;
      pos_new += pos_off;
    }

    pos_off = strspn(buff_org + pos_org, chars);
    if(pos_off > 0)
    {
      pos_org += pos_off;
    }
  }
  buff_new[pos_new + 1] = '\0';
  buff_new = util_realloc(buff_new, (pos_new + 1) * sizeof buff_new);

  return buff_new;
}



/*****************************************************************/



void util_float_to_double(double *double_ptr , const float *float_ptr , int size) {
  int i;
  for (i=0; i < size; i++) 
    double_ptr[i] = float_ptr[i];
}


void util_double_to_float(float *float_ptr , const double *double_ptr , int size) {
  int i;
  for (i=0; i < size; i++)
    float_ptr[i] = double_ptr[i];
}


/*****************************************************************/

/*  
   The util_fwrite_string / util_fread_string are BROKEN when it comes
   to NULL / versus an empty string "":

    1. Writing a "" string what is actually written to disk is: "0\0",
       whereas the disk content when writing NULL is "0".

    2. When reading back we find the '0' - but it is impossible to
       determine whether we should interpret this as a NULL or as "".

   When the harm was done, with files allover the place, it is "solved"
   as follows:

    1. Nothing is changed when writing NULL => '0' to disk.
    
    2. When writing "" => '-1\0' to disk. The -1 is the magic length
       signifying that the following string is "".
*/



void util_fwrite_string(const char * s, FILE *stream) {
  int len = 0;
  if (s != NULL) {
    len = strlen(s);
    if (len == 0) 
      util_fwrite_int(-1 , stream);  /* Writing magic string for "" */
    else
      util_fwrite(&len , sizeof len , 1       , stream , __func__);
    util_fwrite(s    , 1          , len + 1 , stream , __func__);
  } else
    util_fwrite(&len , sizeof len , 1       , stream , __func__);
}



char * util_fread_alloc_string(FILE *stream) {
  int len;
  char *s = NULL;
  util_fread(&len , sizeof len , 1 , stream , __func__);
  if (len > 0) {
    s = util_calloc(len + 1 , sizeof * s );
    util_fread(s , 1 , len + 1 , stream , __func__);
  } else if (len == -1) /* Magic length for "" */ {
    s = util_calloc(1 , sizeof * s );
    util_fread(s , 1 , 1 , stream , __func__);
  }
  return s;
}


char * util_fread_realloc_string(char * old_s , FILE *stream) {
  int len;
  char *s = NULL;
  util_fread(&len , sizeof len , 1 , stream , __func__);
  if (len > 0) {
    s = util_realloc(old_s , len + 1 );
    util_fread(s , 1 , len + 1 , stream , __func__);
  } else if (len == -1) /* Magic length for "" */ {
    s = util_realloc(s , 1 );
    util_fread(s , 1 , 1 , stream , __func__);
  } 
  return s;
}


void util_fskip_string(FILE *stream) {
  int len;
  util_fread(&len , sizeof len , 1 , stream , __func__);
  if (len == 0)        
    return;                                  /* The user has written NULL with util_fwrite_string(). */ 
  else if (len == -1)  
    fseek( stream , 1 , SEEK_CUR);           /* Magic length for "" - skip the '\0' */
  else
    fseek(stream , len + 1 , SEEK_CUR);      /* Skip the data in a normal string. */
}



void util_fwrite_bool     (bool value , FILE * stream)   { UTIL_FWRITE_SCALAR(value , stream); }
void util_fwrite_int      (int value , FILE * stream)    { UTIL_FWRITE_SCALAR(value , stream); }
void util_fwrite_time_t   (time_t value , FILE * stream)    { UTIL_FWRITE_SCALAR(value , stream); }
void util_fwrite_long  (long value , FILE * stream)    { UTIL_FWRITE_SCALAR(value , stream); }
void util_fwrite_double(double value , FILE * stream) { UTIL_FWRITE_SCALAR(value , stream); }

void util_fwrite_int_vector   (const int * value    , int size , FILE * stream, const char * caller) { util_fwrite(value , sizeof * value, size , stream, caller); }
void util_fwrite_double_vector(const double * value , int size , FILE * stream, const char * caller) { util_fwrite(value , sizeof * value, size , stream, caller); }
void util_fwrite_char_vector  (const char * value   , int size , FILE * stream, const char * caller) { util_fwrite(value , sizeof * value, size , stream, caller); }

void util_fread_char_vector(char * ptr , int size , FILE * stream , const char * caller) {
  util_fread(ptr , sizeof * ptr , size , stream , caller);
}


double util_fread_double(FILE * stream) {
  double file_value;
  UTIL_FREAD_SCALAR(file_value , stream);
  return file_value;
}

int util_fread_int(FILE * stream) {
  int file_value;
  UTIL_FREAD_SCALAR(file_value , stream);
  return file_value;
}

time_t util_fread_time_t(FILE * stream) {
  time_t file_value;
  UTIL_FREAD_SCALAR(file_value , stream);
  return file_value;
}


long util_fread_long(FILE * stream) {
  long file_value;
  UTIL_FREAD_SCALAR(file_value , stream);
  return file_value;
}


bool util_fread_bool(FILE * stream) {
  bool file_value;
  UTIL_FREAD_SCALAR(file_value , stream);
  return file_value;
}


void util_fskip_int(FILE * stream) {
  fseek( stream , sizeof (int) , SEEK_CUR);
}

void util_fskip_long(FILE * stream) {
  fseek( stream , sizeof (long) , SEEK_CUR);
}

void util_fskip_bool(FILE * stream) {
  fseek( stream , sizeof (bool) , SEEK_CUR);
}


/*****************************************************************/

time_t util_time_t_min(time_t a , time_t b) {
  return (a < b) ? a : b;
}

time_t util_time_t_max(time_t a , time_t b) {
  return (a > b) ? a : b;
}

size_t util_size_t_min(size_t a , size_t b) {
  return (a < b) ? a : b;
}

size_t util_size_t_max(size_t a , size_t b) {
  return (a > b) ? a : b;
}

int util_int_min(int a , int b) {
  return (a < b) ? a : b;
}

double util_double_min(double a , double b) {
  return (a < b) ? a : b;
}

float util_float_min(float a , float b) {
  return (a < b) ? a : b;
}

int util_int_max(int a , int b) {
  return (a > b) ? a : b;
}

long int util_long_max(long int a , long int b) {
  return (a > b) ? a : b;
}

double util_double_max(double a , double b) {
  return (a > b) ? a : b;
}

float util_float_max(float a , float b) {;
  return (a > b) ? a : b;
}

void util_update_int_max_min(int value , int * max , int * min) {
  *min = util_int_min( value , *min);
  *max = util_int_max( value , *max);
}

void util_update_float_max_min(float value , float * max , float * min) {
  *min = util_float_min(value , *min);
  *max = util_float_max(value , *max);
}

void util_update_double_max_min(double value , double * max , double * min) {
  *min = util_double_min(value , *min);
  *max = util_double_max(value , *max);
}
  

void util_apply_double_limits(double * value , double min_value , double max_value) {
  if (*value < min_value)
    *value = min_value;
  else if (*value > max_value)
    *value = max_value;
}

void util_apply_float_limits(float * value , float min_value , float max_value) {
  if (*value < min_value)
    *value = min_value;
  else if (*value > max_value)
    *value = max_value;
}

void util_apply_int_limits(int * value , int min_value , int max_value) {
  if (*value < min_value)
    *value = min_value;
  else if (*value > max_value)
    *value = max_value;
}



/**
   Scans through a vector of doubles, and finds min and max
   values. They are returned by reference.
*/
  
void util_double_vector_max_min(int N , const double *vector, double *_max , double *_min) {
  double min =  1e100; /* How should this be done ??? */
  double max = -1e100;
  int i;
  for (i = 0; i < N; i++) {
    if (vector[i] > max)
      max = vector[i];

    /* Can not have else here - because same item might succed on both tests. */
    
    if (vector[i] < min)
      min = vector[i];
  }
  *_max = max;
  *_min = min;
}



double util_double_vector_mean(int N, const double * vector) {
  double mean = 0.0;
  int i;
  for(i=0; i<N; i++)
    mean = mean + vector[i];

  return mean / N;
}



double util_double_vector_stddev(int N, const double * vector) {
  if(N <= 1)
    return 0.0;
  {
          double   stddev         = 0.0;
          double   mean           = util_double_vector_mean(N, vector);
          double * vector_shifted = util_calloc(N , sizeof *vector_shifted);
  
          {
          int i;
          for(i=0; i<N; i++)
                vector_shifted[i] = vector[i] - mean;

          for(i=0; i<N; i++)
                stddev = stddev + vector_shifted[i] * vector_shifted[i];
          }
          free(vector_shifted);

          return sqrt( stddev / (N-1));
  }
}


/*****************************************************************/





   
/**
   This function will update *value so that on return ALL bits which
   are set in bitmask, are also set in value. No other bits in *value
   should be modified - i.e. it is a logical or.
*/

void util_bitmask_on(int * value , int mask) {
  int tmp = *value;
  tmp = (tmp | mask);
  *value = tmp;
}




FILE * util_fopen(const char * filename , const char * mode) {
  FILE * stream = fopen(filename , mode);
  if (stream == NULL) 
    util_abort("%s: failed to open:%s with mode:\'%s\' - error:%s(%d) \n",__func__ , filename , mode , strerror(errno) , errno);
  
  return stream;
}



/**
   This micro function is only provided for the convenience of java
   wrapping; if you wonder "What on earth should I use this function
   for" - you can just forget about it.
*/

void util_fclose( FILE * stream ) {
  fclose( stream );
}



/**
   This function will open 'filename' with mode 'mode'. If the mode is
   for write or append (w|a) and the open fails with ENOENT we will
   try to make the path compponent.

   So - the whole point about this function is that for writing it
   should be possible to safely call:

     util_mkdir_fopen("/some/path/to/file.txt" , "w");
     
   without first enusring that /some/path/to exists.
*/

FILE * util_mkdir_fopen( const char * filename , const char * mode ) {
  FILE* stream = fopen( filename , mode);
  if (stream == NULL) {
    if (errno == ENOENT) {
      if (mode[0] == 'w' || mode[0] == 'a') {
        char * path;
        util_alloc_file_components(filename , &path , NULL , NULL);
        if (path != NULL) {
          util_make_path( path );
          free( path );
        }
      }
    }
    /* Let the eventual util_abort() come in the main util_fopen function. */
    return util_fopen( filename , mode );
  } else
    return stream;
}



void util_fwrite(const void *ptr , size_t element_size , size_t items, FILE * stream , const char * caller) {
  int items_written = fwrite(ptr , element_size , items , stream);
  if (items_written != items) 
    util_abort("%s/%s: only wrote %d/%d items to disk - aborting: %s(%d) .\n",caller , __func__ , items_written , items , strerror(errno) , errno);
}


void util_fread(void *ptr , size_t element_size , size_t items, FILE * stream , const char * caller) {
  int items_read = fread(ptr , element_size , items , stream);
  if (items_read != items) 
    util_abort("%s/%s: only read %d/%d items from disk - aborting.\n %s(%d) \n",caller , __func__ , items_read , items , strerror(errno) , errno);
}



void util_fread_from_buffer(void * ptr , size_t element_size , size_t items , char ** buffer) {
  int bytes = element_size * items;
  memcpy( ptr , *buffer , bytes);
  *buffer += bytes;
}



#undef ABORT_READ
#undef ABORT_WRITE


/*****************************************************************/

void * util_realloc(void * old_ptr , size_t new_size ) {
  /* The realloc documentation as ambigous regarding realloc() with size 0 - WE return NULL. */
  if (new_size == 0) { 
    if (old_ptr != NULL)
      free(old_ptr);
    return NULL;
  } else {
    void * tmp = realloc(old_ptr , new_size);
    if (tmp == NULL)
      util_abort("%s: failed to realloc %d bytes - aborting \n",__func__ , new_size);
    return tmp;
  }
}


/**
   This function is a super-thin wrapper around malloc. It allocates
   the number of bytes you ask for. If the return value from malloc()
   is NULL the routine will abort().

   If you are actually interested in handling malloc() failures in a
   decent way, you should not use this routine.
*/



static void * util_malloc__(size_t size) {
  void * data;
  if (size == 0) 
    /* 
       Not entirely clear from documentation what you get when you
       call malloc( 0 ); this code will return NULL in that case.
    */
    data = NULL;
  else {
    data = malloc( size );
    if (data == NULL) 
      util_abort("%s: failed to allocate %zu bytes - aborting \n",__func__ , size);

    /* 
       Initializing with something different from zero - hopefully
       errors will pop up more easily this way?
    */
    memset(data , 255 , size);
  }
  return data;
}

void * util_malloc(size_t size) {
  return util_malloc__( size );
}


void * util_calloc( size_t elements , size_t element_size ) {
  return util_malloc( elements * element_size );
}


/**
   Allocates byte_size bytes of storage, and initializes content with
   the value found in src.
*/

void * util_alloc_copy(const void * src , size_t byte_size ) {
  if (byte_size == 0 && src == NULL)
    return NULL;
  {
    void * new = util_malloc(byte_size );
    memcpy(new , src , byte_size);
    return new;
  }
}



void * util_realloc_copy(void * org_ptr , const void * src , size_t byte_size ) {
  if (byte_size == 0 && src == NULL) 
    return util_realloc( org_ptr , 0 );
  {
    void * new = util_realloc(org_ptr , byte_size );
    memcpy(new , src , byte_size);
    return new;
  }
}





static void util_display_prompt(const char * prompt , int prompt_len2) {
  int i;
  printf("%s" , prompt);
  for (i=0; i < util_int_max(strlen(prompt) , prompt_len2) - strlen(prompt); i++)
    fputc(' ' , stdout);
  printf(": ");
}



void util_read_string(const char * prompt , int prompt_len , char * s) {
  util_display_prompt(prompt , prompt_len);
  fscanf(stdin , "%s" , s);
}


void util_read_path(const char * prompt , int prompt_len , bool must_exist , char * path) {
  bool ok = false;
  while (!ok) {
    util_read_string(prompt , prompt_len , path);
    if (must_exist)
      ok = util_is_directory(path);
    else
      ok = true;
    if (!ok) 
      fprintf(stderr,"Path: %s does not exist - try again.\n",path);
  }
}

/*
  exist_status == 0: Just read a string; do not check if it exist or not.
  exist_status == 1: Must be existing file. 
  exist_status == 2: Must NOT exist as entry.
*/

char * util_fscanf_alloc_filename(const char * prompt , int prompt_len , int exist_status) {
  char * filename = NULL;
  while (filename == NULL) {
    util_printf_prompt(prompt , prompt_len , '=' , "=> ");
    filename = util_alloc_stdin_line();
    if (filename != NULL) {
      if (exist_status != 0) {
        if (exist_status == 1) {
          if (!util_file_exists(filename)) {
            fprintf(stderr,"Sorry: %s does not exist. \n",filename);
            free( filename );
            filename = NULL;
          } 
        } else if (exist_status == 2) {
          if (util_entry_exists( filename )) {
            fprintf(stderr,"Sorry: entry %s already exists. \n",filename);
            free( filename );
            filename = NULL;
          }
        }
      }
    }
  }
  return filename;
}


/*****************************************************************/


/**
   These small functions write formatted values onto a stream. The
   main point about these functions is to avoid creating small one-off
   format strings. The character base_fmt should be 'f' or 'g'
*/

void util_fprintf_double(double value , int width , int decimals , char base_fmt , FILE * stream) {
  char * fmt = util_alloc_sprintf("%c%d.%d%c" , '%' , width , decimals , base_fmt);
  fprintf(stream , fmt , value);
  free(fmt);
}


void util_fprintf_int(int value , int width , FILE * stream) {
  char fmt[32];
  sprintf(fmt , "%%%dd" , width);
  fprintf(stream , fmt , value);
}



void util_fprintf_string(const char * s , int width , string_alignement_type alignement , FILE * stream) {
  char fmt[32];
  int i;
  if (alignement == left_pad) {
    i = 0;
    if (width > strlen(s)) {
      for (i=0; i < (width - strlen(s)); i++) 
        fputc(' ' , stream);
    }
    fprintf(stream , s);
  } else if (alignement == right_pad) {
    sprintf(fmt , "%%-%ds" , width);
    fprintf(stream , fmt , s);
  } else {
    int total_pad  = width - strlen(s);
    int front_pad  = total_pad / 2;
    int back_pad   = total_pad - front_pad;
    int i;
    util_fprintf_string(s , front_pad + strlen(s) , left_pad , stream);
    for (i=0; i < back_pad; i++)
      fputc(' ' , stream);
  }
}





/**
   This function allocates a string acoording to the fmt
   specification, and arguments. The arguments (except the format) are
   entered as a variable length argument list, and the function is
   basically a thin wrapper around vsnprintf().
   
   Example of usage:
   
   char * s = util_alloc_sprintf("/%s/File:%04d/%s" , "prefix" , 67 , "Suffix");
   
   => s = /prefix/File:0067/Suffix
   
   Observe that when it is based in vsnprintf() essentially no
   error-checking is performed.
*/

char * util_alloc_sprintf_va(const char * fmt , va_list ap) {
  char *s = NULL;
  int length;
  va_list tmp_va;
  UTIL_VA_COPY(tmp_va , ap);
  length = vsnprintf(NULL , 0 , fmt , tmp_va);
  s = util_calloc(length + 1 , sizeof * s );
  vsprintf(s , fmt , ap);
  return s;
}


char * util_alloc_sprintf(const char * fmt , ...) {
  char * s;
  va_list ap;
  va_start(ap , fmt);
  s = util_alloc_sprintf_va(fmt , ap);
  va_end(ap);
  return s;
}


char * util_alloc_sprintf_escape(const char * src , int max_escape) {
  if (src == NULL)
    return NULL;
  
  if (max_escape == 0)
    max_escape = strlen( src );
  
  {
    const int src_len = strlen( src );
    char * target = util_calloc( max_escape + strlen(src) + 1 , sizeof * target);

    int escape_count = 0;
    int src_offset = 0;
    int target_offset = 0;
    
    while (true) {
      if (src[src_offset] == '%') {
        if (escape_count < max_escape) {
          target[target_offset] = '%';
          target_offset++;
          escape_count++;
        }
      }
      target[target_offset] = src[src_offset];
      target_offset++;
      src_offset++;
      if (src_offset == src_len) 
        break;
    }
    target[target_offset] = '\0';
    target = util_realloc( target , (target_offset + 1) * sizeof * target);
    return target;
  }
}


/*
char * util_realloc_sprintf(char * s , const char * fmt , ...) {
  va_list ap;
  va_start(ap , fmt);
  printf("1: %s  s:%s / p:%p \n",__func__ , s , s );
  {
    int length;
    va_list tmp_va;
    va_copy(tmp_va , ap);
    length = vsnprintf(s , 0 , fmt , tmp_va);
    s = util_realloc(s , length + 1 , __func__);
    printf("2: %s  s:%s / p:%p  length:%d\n",__func__ , s , s );
  }
  vsprintf(s , fmt , ap);
  va_end(ap);
  return s;
}
*/

char * util_realloc_sprintf(char * s , const char * fmt , ...) {
  char * new_s;
  va_list ap;
  va_start(ap , fmt);
  
  new_s = util_alloc_sprintf_va( fmt , ap );
  util_safe_free(s);
  
  va_end(ap);
  return new_s;
}







/**
  This function is intended to be installed as a signal
  handler, so we can get a traceback from signals like SIGSEGV.
  
  To install the signal handler:

  #include <signal.h>
  ....
  ....
  signal(SIGSEGV , util_abort_signal);


  The various signals can be found in: /usr/include/bits/signum.h
*/
  

void util_abort_signal(int signal) {
  util_abort("Program recieved signal:%d\n" , signal);
}


void util_exit(const char * fmt , ...) {
  va_list ap;
  va_start(ap , fmt);
  vfprintf(stderr , fmt , ap);
  va_end(ap);
  exit(1);
}




    
  
/**
   This function is quite dangerous - it will always return something;
   it is the responsability of the calling scope to check that it
   makes sense. Will return 0 on input NULL.  
*/

int util_get_type( void * data ) {
  if (data == NULL)
    return 0;
  else
    return ((int *) data)[0];
}











/**
   This function finds the current linenumber (by counting '\n'
   characters) in a currently open stream. It is an extremely
   primitive routine, and should only be used exceptionally.

   Observe that it implements "natural" counting, starting at line_nr
   1, and not line_nr 0.
*/

int util_get_current_linenr(FILE * stream) {
  long init_pos = ftell(stream);
  int line_nr   = 0;
  fseek( stream , 0L , SEEK_SET);
  {
    int char_nr;
    int c;
    for (char_nr = 0; char_nr < init_pos; char_nr++) {
      c = fgetc(stream);
      if (c == '\n')
        line_nr++;
    }
  }
  return line_nr;
}





const char * util_enum_iget( int index , int size , const util_enum_element_type * enum_defs , int * value) {
  if ((index < 0) || (index >= size)) {
    *value = -1;
    return NULL;
  } else {
    const util_enum_element_type elm = enum_defs[ index ];
    *value = elm.value;
    return elm.name;
  }
}


static char * __abort_program_message = NULL;                      /* Can use util_abort_append_version_info() to fill this with 
                                                                      version info+++ wich will be printed when util_abort() is called. */
static char * __current_executable    = NULL;


void util_abort_append_version_info(const char * msg) {
  __abort_program_message = util_strcat_realloc( __abort_program_message , msg );
}


void util_abort_free_version_info() {
  util_safe_free( __abort_program_message );
  util_safe_free( __current_executable );

  __current_executable    = NULL;
  __abort_program_message = NULL;
}


void util_abort_set_executable( const char * argv0 ) {
  if (util_is_abs_path(argv0)) 
    __current_executable = util_realloc_string_copy( __current_executable , argv0 );
  else {
    char * executable;
    if (util_is_executable( argv0 )) 
      executable = util_alloc_realpath(argv0);
    else
      executable = util_alloc_PATH_executable( argv0 );

    util_abort_set_executable( executable );
    free( executable );
  }
}



/*****************************************************************/

/*
  Will check if the vector @data contains the element @value. The
  @data vector should be sorted in increasing order prior to calling
  this function. If the vector is not correctly sorted this will be
  crash and burn.

  If the element is found the index is returned, otherwise the value -1
  is returned.
*/

#define CONTAINS(TYPE) int util_sorted_contains_ ## TYPE(const TYPE * data , int size , TYPE value) { \
  if ((data[0] == value))                               \
     return 0;                                          \
  else if ((data[size - 1] == value))                   \
     return size - 1;                                   \
  else if ((value < data[0]) || (value > data[size-1])) \
     return -1;                                         \
  else {                                                \
     int index1 = 0;                                    \
     int index2 = size - 1;                             \
     while (true) {                                     \
        int center_index = (index1 + index2) / 2;       \
        TYPE center_value = data[center_index];         \
        if (center_value == value)                      \
           return center_index;                         \
        else {                                          \
          if (value < center_value)                     \
            index2 = center_index;                      \
          else                                          \
            index1 = center_index;                      \
          if ((index2 - index1) == 1)                   \
            return -1;                                  \
        }                                               \
     }                                                  \
  }                                                     \
}                                            

CONTAINS(int)
CONTAINS(time_t)
CONTAINS(size_t)
#undef CONTAINS    

/*****************************************************************/




int util_fnmatch( const char * pattern , const char * string ) {
#ifdef HAVE_FNMATCH
  return fnmatch( pattern , string , 0 );
#else
#pragma comment(lib , "shlwapi.lib");
  bool match = PathMatchSpec( string , pattern ); // shlwapi
  if (match)
    return 0;
  else
    return 1;
    
#endif
}

/*****************************************************************/
/* Conditional compilation; this last section includes several
   functions which are included if certain features like e.g. fork()
   are present. */

// Observe that there is some really ugly #ifdef HAVE_REALPATH in the
// main code.


void util_localtime( time_t * t , struct tm * ts ) {
#ifdef HAVE_LOCALTIME_R
  localtime_r( t , ts );
#else
  struct tm * ts_shared = localtime( t );
  memcpy( ts , ts_shared , sizeof * ts );
#endif
}

#ifdef HAVE_FORK
#include "util_fork.c"
#endif

#ifdef WITH_ZLIB
#include "util_zlib.c"
#endif

#ifdef HAVE_GETUID
#include "util_getuid.c"
#endif

#ifdef HAVE_LOCKF
#include "util_lockf.c"
#endif


#include "util_env.c"

#ifdef HAVE_SYMLINK
#include "util_symlink.c"
#else
bool util_is_link(const char * path) {
  return false;
}

char * util_alloc_link_target(const char * link) {
  return util_alloc_string_copy( link );
}
#endif



#ifdef HAVE_UTIL_ABORT
#include "util_abort_gnu.c"
#else
#include "util_abort_simple.c"
#endif


#ifdef HAVE_OPENDIR
#include "util_opendir.c"
#endif


#ifdef HAVE_ROUND
int util_roundf( float x ) { return roundf(x); }
int util_round( double x ) { return round(x); }
#else
int util_roundf( float x ) { return (int) (x + 0.5); }
int util_round( double x ) { return (int) (x + 0.5); }
#endif

#include "util_path.c"

int util_type_get_id( const void * data ) {
  int type_id = ((const int*) data)[0];
  return type_id;
}  



