ResInsight/ThirdParty/Ert/include/util.h

441 lines
20 KiB
C

/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'util.h' 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.
*/
#ifndef __UTIL_H__
#define __UTIL_H__
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <stdarg.h>
#ifdef HAVE_GETUID
#include <sys/stat.h>
#include <sys/types.h>
#endif
#define UTIL_PATH_SEP_STRING "/" /* A \0 terminated separator used when we want a (char *) instance. */
#define UTIL_PATH_SEP_CHAR '/' /* A simple character used when we want an actual char instance (i.e. not a pointer). */
#define UTIL_NEWLINE_STRING " \n"
#define UTIL_DEFAULT_MKDIR_MODE 0777 /* Directories are by default created with mode a+rwx - and then comes the umask ... */
#ifdef __cplusplus
extern"C" {
#endif
/*****************************************************************/
/*
*/
/*****************************************************************/
typedef void (walk_file_callback_ftype) (const char * , /* The current directory */
const char * , /* The current file / directory */
void *); /* Arbitrary argument */
typedef bool (walk_dir_callback_ftype) (const char * , /* The current directory */
const char * , /* The current file / directory */
int , /* The current depth in the file hiearcrcy. */
void *); /* Arbitrary argument */
typedef enum {left_pad = 0,
right_pad = 1,
center_pad = 2} string_alignement_type;
//#define UTIL_CXX_MALLOC(var , num_elm) (typeof (var)) util_malloc( (num_elm) * sizeof var)
void util_bitmask_on(int * , int );
time_t util_make_datetime(int , int , int , int , int , int );
void util_fprintf_datetime(time_t , FILE * );
void util_fprintf_date(time_t , FILE * );
time_t util_make_date(int , int , int);
void util_inplace_forward_days(time_t * , double);
double util_difftime(time_t , time_t , int * , int * , int * , int *);
double util_difftime_days(time_t , time_t );
bool util_file_newer( const char * file , time_t t0);
bool util_file_older( const char * file , time_t t0);
char * util_alloc_date_string( time_t t );
char * util_alloc_date_stamp( );
double util_pow10(double x);
bool util_char_in(char c, int , const char *);
char * util_alloc_sprintf_va(const char * fmt , va_list ap);
char * util_alloc_sprintf(const char * , ...);
char * util_realloc_sprintf(char * , const char * , ...);
void util_fprintf_int(int , int , FILE * );
void util_fprintf_string(const char * , int , string_alignement_type , FILE * );
void util_fprintf_double(double , int , int , char , FILE *);
bool util_fscanf_date(FILE * , time_t *);
bool util_sscanf_date(const char * , time_t *);
char * util_alloc_stdin_line();
char * util_realloc_stdin_line(char * );
bool util_is_executable(const char * );
bool util_entry_exists( const char * entry );
bool util_file_exists(const char *);
bool util_is_abs_path(const char * );
char * util_alloc_abs_path( const char * path );
bool util_fmt_bit8 (const char *);
bool util_fmt_bit8_stream(FILE * );
void util_make_path (const char *);
char * util_newest_file(const char *, const char *);
double util_file_difftime(const char * , const char *);
bool util_file_update_required(const char *, const char *);
size_t util_file_size(const char *);
void util_clear_directory(const char *path, bool strict_uid , bool unlink_root);
void util_unlink_existing(const char *filename);
void util_strupr(char *);
bool util_string_equal(const char * s1 , const char * s2 );
char * util_alloc_strupr_copy(const char * );
void util_string_tr(char * , char , char);
bool util_copy_stream(FILE *, FILE *, int , void * , bool abort_on_error);
void util_move_file(const char * src_file , const char * target_file);
void util_move_file4( const char * src_name , const char * target_name , const char *src_path , const char * target_path);
bool util_copy_file(const char * , const char * );
char * util_alloc_cwd(void);
char * util_alloc_realpath(const char * );
bool util_string_match(const char * string , const char * pattern);
bool util_string_has_wildcard( const char * s);
bool util_entry_readable( const char * entry );
void util_ftruncate(FILE * stream , long size);
void util_usleep( unsigned long micro_seconds );
char * util_blocking_alloc_stdin_line(unsigned long );
int util_roundf( float x );
int util_round( double x );
#ifdef HAVE_VA_COPY
#define UTIL_VA_COPY(target,src) va_copy(target,src)
#else
#define UTIL_VA_COPY(target,src) target = src
#endif
#ifdef HAVE_OPENDIR
void util_copy_directory(const char * , const char * , const char *);
void util_walk_directory(const char * root_path , walk_file_callback_ftype * file_callback , void * file_callback_arg , walk_dir_callback_ftype * dir_callback , void * dir_callback_arg);
#endif
#ifdef HAVE_GETUID
uid_t util_get_entry_uid( const char * file );
bool util_addmode_if_owner( const char * filename , mode_t add_mode );
bool util_delmode_if_owner( const char * filename , mode_t del_mode);
bool util_chmod_if_owner( const char * filename , mode_t new_mode);
#endif
#ifdef HAVE_PROC
bool util_proc_alive(pid_t pid);
#endif
int util_forward_line(FILE * , bool * );
void util_rewind_line(FILE *);
int util_count_content_file_lines(FILE * );
int util_count_file_lines(FILE * );
FILE * util_mkdir_fopen( const char * filename , const char * mode );
int util_fmove( FILE * stream , long offset , long shift);
FILE * util_fopen(const char * , const char *);
void util_fclose( FILE * stream );
bool util_fopen_test(const char *, const char *);
void util_alloc_file_components(const char * , char ** , char **, char **);
//char * util_realloc_full_path(char * , const char *, const char *);
char * util_alloc_tmp_file(const char * , const char * , bool );
char * util_fscanf_alloc_line(FILE *, bool *);
char * util_fscanf_realloc_line(FILE *, bool * , char *);
char * util_fscanf_alloc_token(FILE * );
void util_fskip_token(FILE * );
void util_fskip_space(FILE * , bool *);
void util_fskip_chars(FILE * , const char * , bool *);
void util_fskip_cchars(FILE * , const char * , bool *);
bool util_fscanf_int(FILE * , int * );
bool util_fscanf_bool(FILE * stream , bool * value);
bool util_sscanf_bool(const char * , bool *);
bool util_sscanf_octal_int(const char * buffer , unsigned int * value);
int util_strcmp_int( const char * s1 , const char * s2);
int util_strcmp_float( const char * s1 , const char * s2);
bool util_sscanf_int(const char * , int * );
const char * util_parse_int(const char * , int * , bool *);
const char * util_skip_sep(const char * , const char * , bool *);
int util_scanf_int_with_limits(const char * , int , int , int );
char * util_scanf_int_with_limits_return_char(const char * , int , int , int );
void util_printf_prompt(const char * , int , char , const char *);
int util_scanf_int(const char * , int);
char * util_scanf_int_return_char(const char * , int);
double util_scanf_double(const char * prompt , int prompt_len);
char * util_scanf_alloc_string(const char * );
bool util_sscanf_double(const char * , double * );
//char * util_alloc_full_path(const char *, const char *);
char * util_alloc_filename(const char * , const char * , const char * );
char * util_realloc_filename(char * , const char * , const char * , const char * );
char * util_alloc_strip_copy(const char *);
char * util_realloc_strip_copy(char *);
void util_set_strip_copy(char * , const char *);
char * util_alloc_string_sum(const char ** , int);
char * util_strcat_realloc(char *, const char * );
char * util_alloc_string_copy(const char *);
char ** util_stringlist_append_copy(char ** , int , const char * );
char ** util_stringlist_append_ref(char ** , int , const char * );
char ** util_alloc_stringlist_copy(const char **, int );
void util_split_string(const char *, const char *, int *, char ***);
void util_path_split(const char * , int *, char ***);
void util_binary_split_string(const char * , const char * , bool , char ** , char ** );
char * util_alloc_joined_string(const char ** , int , const char * );
char * util_alloc_multiline_string(const char ** , int );
char * util_string_replace_alloc(const char *, const char *, const char *);
char * util_string_replacen_alloc(const char *, int , const char ** , const char **);
int util_string_replace_inplace(char ** , const char * , const char *);
char * util_string_strip_chars_alloc(const char *, const char * );
char * util_realloc_string_copy(char * , const char *);
char * util_realloc_substring_copy(char * , const char *, int N);
char * util_realloc_dequoted_string(char *);
char * util_alloc_dequoted_copy(const char *s);
void util_safe_free(void *);
void util_free_stringlist(char **, int );
char * util_alloc_substring_copy(const char *, int offset , int N);
bool util_is_directory(const char * );
bool util_is_file(const char * );
void util_set_datetime_values(time_t , int * , int * , int * , int * , int * , int *);
void util_set_date_values(time_t , int * , int * , int * );
void util_fread_from_buffer(void * , size_t , size_t , char ** );
unsigned int util_clock_seed( );
void util_fread_dev_random(int , char * );
void util_fread_dev_urandom(int , char * );
char * util_alloc_string_copy(const char *);
bool util_string_isspace(const char * s);
void util_exit(const char * fmt , ...);
void util_abort(const char * fmt , ...);
void util_abort_signal(int );
void util_abort_append_version_info(const char * );
void util_abort_free_version_info();
void util_abort_set_executable( const char * executable );
void * util_realloc(void * , size_t );
void * util_malloc(size_t );
void * util_calloc( size_t elements , size_t element_size );
void * util_realloc_copy(void * org_ptr , const void * src , size_t byte_size );
void * util_alloc_copy(const void * , size_t );
void util_double_to_float(float * , const double * , int );
void util_float_to_double(double * , const float * , int );
int util_get_month_nr(const char * );
char * util_fread_alloc_file_content(const char * , int *);
void util_fwrite_string(const char * , FILE *);
char * util_fread_realloc_string(char * , FILE *);
char * util_fread_alloc_string(FILE *);
void util_fskip_string(FILE *stream);
void util_endian_flip_vector(void * data , int element_size , int elements);
int util_proc_mem_free(void);
void util_apply_int_limits(int * , int , int );
void util_apply_float_limits(float * , float , float );
void util_apply_double_limits(double * , double , double );
double util_double_vector_mean(int , const double * );
double util_double_vector_stddev(int , const double * );
void util_double_vector_max_min(int , const double *, double * , double *);
void util_update_double_max_min(double , double * , double * );
void util_update_float_max_min(float , float * , float * );
void util_update_int_max_min(int , int * , int * );
float util_float_max (float , float );
long int util_long_max(long int a , long int b);
int util_int_max (int , int);
double util_double_max(double , double );
float util_float_min (float , float );
int util_int_min (int , int);
size_t util_size_t_min(size_t a , size_t b);
size_t util_size_t_max(size_t a , size_t b);
time_t util_time_t_min(time_t a , time_t b);
time_t util_time_t_max(time_t a , time_t b);
double util_double_min(double , double );
void util_fskip_lines(FILE * , int);
bool util_same_file(const char * , const char * );
void util_read_path(const char * , int , bool , char * );
char * util_fscanf_alloc_filename(const char * , int , int);
void util_read_string(const char * , int , char * );
void util_fread (void *, size_t , size_t , FILE * , const char * );
void util_fwrite(const void *, size_t , size_t , FILE * , const char * );
time_t util_fread_time_t(FILE * stream);
int util_fread_int(FILE * );
long util_fread_long(FILE * );
bool util_fread_bool(FILE * );
double util_fread_double(FILE * stream);
void util_fwrite_int (int , FILE * );
void util_fwrite_long (long , FILE * );
void util_fwrite_bool (bool , FILE * );
void util_fwrite_time_t (time_t , FILE * );
void util_fwrite_double(double , FILE * );
void util_fwrite_int_vector (const int * , int , FILE * , const char * );
void util_fwrite_double_vector(const double * , int , FILE * , const char * );
void util_fread_char_vector(char * , int , FILE * , const char * );
int util_type_get_id( const void * data );
char * util_alloc_realpath(const char * );
bool util_sscanf_bytesize(const char * , size_t *);
void util_sscanf_active_range(const char * , int , bool * );
int * util_sscanf_alloc_active_list(const char * , int * );
int util_get_current_linenr(FILE * stream);
const char * util_update_path_var(const char * , const char * , bool );
int util_get_type( void * data );
void util_fskip_int(FILE * stream);
void util_fskip_long(FILE * stream);
void util_fskip_bool(FILE * stream);
bool util_fseek_string(FILE * stream , const char * string , bool skip_string , bool case_sensitive);
char * util_fscanf_alloc_upto(FILE * stream , const char * stop_string, bool include_stop_string);
bool util_files_equal( const char * file1 , const char * file2 );
double util_kahan_sum(const double *data, size_t N);
int util_fnmatch( const char * pattern , const char * string );
void util_localtime( time_t * t , struct tm * ts );
char * util_alloc_PATH_executable(const char * executable );
char * util_isscanf_alloc_envvar( const char * string , int env_index );
void util_setenv( const char * variable , const char * value);
const char * util_interp_setenv( const char * variable , const char * value);
void util_unsetenv( const char * variable);
char * util_alloc_envvar( const char * value );
bool util_is_link(const char * ); // Will always return false on windows
#define UTIL_FWRITE_SCALAR(s,stream) { if (fwrite(&s , sizeof s , 1 , stream) != 1) util_abort("%s: write failed: %s\n",__func__ , strerror(errno)); }
#define UTIL_FREAD_SCALAR(s,stream) { if (fread(&s , sizeof s , 1 , stream) != 1) util_abort("%s: read failed: %s\n",__func__ , strerror(errno)); }
#define UTIL_FWRITE_VECTOR(s,n,stream) { if (fwrite(s , sizeof s , (n) , stream) != (n)) util_abort("%s: write failed: %s \n",__func__ , strerror(errno)); }
#define UTIL_FREAD_VECTOR(s,n,stream) { if (fread(s , sizeof s , (n) , stream) != (n)) util_abort("%s: read failed: %s \n",__func__ , strerror(errno)); }
#define CONTAINS_HEADER(TYPE) int util_sorted_contains_ ## TYPE(const TYPE * data , int size , TYPE value);
CONTAINS_HEADER(int);
CONTAINS_HEADER(time_t);
CONTAINS_HEADER(size_t);
#undef CONTAINS_HEADER
/*****************************************************************/
/*
The code below here is a simple functionality to support 'enum
introspection'; the point is that when calling the library functions
from Python/ctypes it is very valuable to have access to the enum
values from the Python side. The enum defintions is just used during
the compile phase, and then subsequently dropped. It is therefor
impossible to determine enum values by inspecting the resulting
object files.
The approach which has been chosen is that each of the enums which
should support 'introspection' from Python should have a function:
const char * <enum>_iget(int index, int * value) {
...
}
which should take an enum element number as input argument and
return a string representation of the corresponding enum element and
also update the value reference to contain the corresponding enum
value. If index is out of range the function should return NULL and
also set value to -1. The python layer can then create an integer
variable with the correct name and value in the calling module.
The util_enum_element_type and the util_enum_iget() function are
convenience functions which can be used to avoid indirectly
repeating the enum definition in the <enum>_iget() function.
In the example below we create the enum definition in normal way in
the header file, and then in addition we repeat the defintion in a
#define a symbol which is used as argument in the <enum>_iget()
function:
header_file:
------------
enum my_enum {
INVALID = 0,
VALUE1 = 2,
VALUE2 = 17
}
// The enum definition is repeated; but at at least at the very same spot of the code.
#define MY_ENUM_DEF { .value = INVALID, .name="INVALID"} , {.value = VALUE1 , .name="VALUE1"} , {.value = VALUE2 , .name="VALUE2"}
#define MY_ENUM_SIZE 3
source file:
------------
const char * my_enum_iget(int index, int * value) {
return util_enum_iget( index , MY_ENUM_SIZE , (const util_enum_element_type []) MY_ENUM_DEF , value);
}
*/
typedef struct {
int value;
const char * name;
} util_enum_element_type;
const char * util_enum_iget( int index , int size , const util_enum_element_type * enum_defs , int * value);
/*****************************************************************/
/* Conditional section below here */
#ifdef HAVE_ZLIB
void util_compress_buffer(const void * , int , void * , unsigned long * );
int util_fread_sizeof_compressed(FILE * stream);
void util_fread_compressed(void * , FILE * );
void * util_fread_alloc_compressed(FILE * );
void util_fwrite_compressed(const void * , int , FILE * );
#endif
#ifdef HAVE_SYMLINK
void util_make_slink(const char *, const char * );
char * util_alloc_link_target(const char * link);
#ifdef HAVE_READLINKAT
char * util_alloc_atlink_target(const char * path , const char * link);
#endif
#endif
#ifdef HAVE_FORK
#include "util_fork.h"
#endif
#ifdef HAVE_LOCKF
FILE * util_fopen_lockf(const char * , const char * );
bool util_try_lockf(const char * , mode_t , int * );
#endif
#ifdef __cplusplus
}
#endif
#endif