#1768 Update libecl to b17c5ffbf2f82594b01037d39ca9440252a10536

This commit is contained in:
Magne Sjaastad
2017-08-29 07:48:38 +02:00
parent a6c526c5ba
commit 7e316edf17
188 changed files with 5064 additions and 7568 deletions

View File

@@ -1,15 +1,33 @@
language: c
compiler:
- gcc
- clang
os:
- linux
- osx
osx_image: xcode7.3
sudo: false
dist: trusty
env:
global:
- ERT_SHOW_BACKTRACE=1
matrix:
- PYTHON_VERSION=2.7; TEST_SUITE="-LE SLOW" # Run all tests not labeled as slow
- PYTHON_VERSION=2.7; TEST_SUITE="-L SLOW_1" # Run all tests labeled as SLOW in group 1
- PYTHON_VERSION=2.7; TEST_SUITE="-L SLOW_2" # Run all tests labeled as SLOW in group 2
- PYTHON_VERSION=3.6; TEST_SUITE="-LE SLOW" # Run all tests not labeled as slow
matrix:
fast_finish: true
include:
exclude:
- os: osx
osx_image: xcode7.3
compiler: clang
- os: linux
sudo: false
compiler: gcc
dist: trusty
- os: linux
compiler: clang
addons:
apt:
@@ -24,35 +42,34 @@ addons:
- cmake
- cmake-data
env:
global:
- ERT_SHOW_BACKTRACE=1
install:
- if [[ "$CC" == "gcc" ]]; then export CXX="g++-4.8"; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
export CONDA_OS=MacOSX;
else
export CONDA_OS=Linux;
fi
- export TRAVIS_PYTHON_VERSION="2.7"
# We do this conditionally because it saves us some downloading if the version is the same.
- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
wget https://repo.continuum.io/miniconda/Miniconda2-latest-${CONDA_OS}-x86_64.sh -O miniconda.sh;
else
wget https://repo.continuum.io/miniconda/Miniconda3-latest-${CONDA_OS}-x86_64.sh -O miniconda.sh;
fi
- bash miniconda.sh -b -p $HOME/miniconda
- export CONDA_HOME="$HOME/miniconda"
- export PATH="$CONDA_HOME/bin:$PATH"
- hash -r
- conda config --set always_yes yes --set changeps1 no
- conda update -q conda
- conda info -a # Useful for debugging any issues with conda
- conda install pylint numpy pandas
- if [[ "$CC" == "gcc" ]]; then export CXX="g++-4.8"; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
export CONDA_OS=MacOSX;
else
export CONDA_OS=Linux;
fi
- if [[ $PYTHON_VERSION == 2.7 ]]; then
export TRAVIS_PYTHON_VERSION="2.7";
fi
# We do this conditionally because it saves us some downloading if the version is the same.
- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
wget https://repo.continuum.io/miniconda/Miniconda2-latest-${CONDA_OS}-x86_64.sh -O miniconda.sh;
else
wget https://repo.continuum.io/miniconda/Miniconda3-latest-${CONDA_OS}-x86_64.sh -O miniconda.sh;
fi
- bash miniconda.sh -b -p $HOME/miniconda
- export CONDA_HOME="$HOME/miniconda"
- export PATH="$CONDA_HOME/bin:$PATH"
- hash -r
- conda config --set always_yes yes --set changeps1 no
- conda update -q conda
- conda info -a # Useful for debugging any issues with conda
- conda install pylint numpy pandas
before_script:
- wget https://raw.githubusercontent.com/Statoil/ert/master/travis/build_total.py
script:
- python build_total.py ecl
- python build_total.py ecl ${TEST_SUITE}

View File

@@ -9,13 +9,37 @@ endif()
#-----------------------------------------------------------------
set( ERT_VERSION_MAJOR 2 ) # Remember to update release notes whenever
set( ERT_VERSION_MINOR 2 ) # you change the ERT_VERSION_MINOR or MAJOR
set( ERT_VERSION_MICRO git ) # with "new in Ert Version X.X.X"!
set( ECL_VERSION_MAJOR 2 ) # Remember to update release notes whenever
set( ECL_VERSION_MINOR 2 ) # you change the ERT_VERSION_MINOR or MAJOR
set( ECL_VERSION_MICRO git ) # with "new in Ert Version X.X.X"!
# If the micro version is not integer, that should be interpreted as a
# development version leading towards version MAJOR.MINOR.0
execute_process(COMMAND date "+%Y-%m-%d %H:%M:%S" OUTPUT_VARIABLE ECL_BUILD_TIME )
string(STRIP "${ECL_BUILD_TIME}" ECL_BUILD_TIME)
find_package(Git)
if(GIT_FOUND)
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT_SHORT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
else()
set( GIT_COMMIT "unknown (git not found!)")
set( GIT_COMMIT_SHORT "unknown (git not found!)")
message( WARNING "Git not found. Build will not contain git revision info." )
endif()
#-----------------------------------------------------------------
option( BUILD_TESTS "Should the tests be built" OFF)
@@ -214,6 +238,8 @@ check_function_exists( setenv HAVE_POSIX_SETENV )
check_function_exists( symlink ERT_HAVE_SYMLINK )
check_function_exists( timegm HAVE_TIMEGM )
check_function_exists( usleep HAVE__USLEEP )
check_function_exists( unlink HAVE_POSIX_UNLINK )
check_function_exists( _unlink HAVE_WINDOWS_UNLINK )
check_symbol_exists(_tzname time.h HAVE_WINDOWS_TZNAME)
check_symbol_exists( tzname time.h HAVE_TZNAME)
@@ -286,7 +312,7 @@ if (ERT_WINDOWS)
else() # Linux or Darwin
execute_process(COMMAND date "+%Y-%m-%d %H:%M:%S" OUTPUT_VARIABLE BUILD_TIME)
endif()
string(STRIP ${BUILD_TIME} BUILD_TIME)
string(STRIP "${BUILD_TIME}" BUILD_TIME)
#-----------------------------------------------------------------
@@ -331,9 +357,6 @@ if (BUILD_PYTHON)
endif()
endif()
if (INSTALL_ERT)
install(EXPORT ecl-config DESTINATION share/cmake/ecl)
endif()
install(EXPORT ecl-config DESTINATION share/cmake/ecl)
export(TARGETS ecl FILE eclConfig.cmake)
export(PACKAGE ecl)

View File

@@ -1,302 +1,60 @@
# libecl [![Build Status](https://travis-ci.org/Statoil/libecl.svg?branch=master)](https://travis-ci.org/Statoil/libecl)
## Coming from OPM?
*libecl* is a package for reading and writing the result files from
the Eclipse reservoir simulator. The file types covered are the
restart, init, rft, summary and grid files. Both unified and
non-unified and formatted and unformatted files are supported.
`libecl` is a package for handling an ensemble of reservoir models, an
important part of that is beeing able to read and write the files from
standard reservoir applications; `libecl` has quite extensive support for
reading and writing the result files from the ECLIPSE reservoir
simulator. The capabilities to read and write ECLIPSE result files is
used by the OPM simulator codes.
*libecl* is mainly developed on *Linux* and *OS X*, in addition there
is a portability layer which ensures that most of the functionality is
available on *Windows*. The main functionality is written in C, and
should typically be linked in in other compiled programs. *libecl* was
initially developed as part of the [Ensemble Reservoir
Tool](http://github.com/Statoil/ert), other applications using
*libecl* are the reservoir simulator flow and Resinsight from the [OPM
project](http://github.com/OPM/).
The `libecl` build system has many configuration options, but when
compiling for OPM you should be able to use the all defaults route:
In addition to the C code there are Python wrappers which make most of
the *libecl* functionality available from Python. For small interactive
scripts, forward models e.t.c. this is recommended way to use *libecl*
functionality.
### Compiling the C code ###
*libecl* uses CMake as build system:
```bash
git clone https://github.com/Statoil/libecl.git
cd libecl
git clone https://github.com/Statoil/*libecl*.git
cd *libecl*
mkdir build
cd build
cmake ..
make
```
If you intend to develop and change *libecl* you should build the tests
by passing `-DBUILD_TESTS=ON` and run the tests with `ctest`.
The OPM build system can find an `libecl` distribution in the sibling
location, i.e. if you have cloned ert beside the opm modules like:
```
libecl/
opm-common/
opm-parser/
opm-material/
...
```
The opm build system will find the ert distribution in-place,
otherwise you should install ert with 'make install' and the normal
cmake machinery of the opm build system should find it.
### Compiling the Python code ###
```
------------------------------------------------------------------------
Python is not a compiled language, but there is a basic "build system"
which does a basic Python syntax check and configures some files to
correctly set up the interaction between the Python classes and the
shared libraries built from the C code.
_________________________________
/ \
| ______ ______ _______ |
| | ____| | __ \ |__ __| |
| | |__ | |__) | | | |
| | __| | _ / | | |
| | |____ | | \ \ | | |
| |______| |_| \_\ |_| |
| |
| Ensemble based Reservoir Tool |
\_________________________________/
You need to install some Python requirements before the Python code
will work:
sudo pip install -r requirements.txt
------------------------------------------------------------------------
```
The Python + cmake interaction is handled in a separate project called
[pycmake](https://github.com/Statoil/pycmake); you can either install
that manually or use the git submodule functionality to fetch the
correct version of `pycmake` into your *libecl* code:
1. `libecl`
2. ECLIPSE utilities.
3. Building `libecl`
1. CMake settings you might want to adjust
4. The code:
1. The different libraries
2. The general structure
3. Python wrappers
5. Tests
git submodule update --init pycmake
------------------------------------------------------------------------
## 1. `libecl`
`libecl` - Ensemble based Reservoir Tool is a tool for managing an ensemble
of reservoir models. The initial motivation for creating `libecl` was a as
tool to do assisted history matching with the Ensemble Kalman Filter
(EnKF). Very briefly, the process of using EnKF for history matching
can be summarized as:
1. Sample initial reservoir parameters from a (Gaussian) initial
distribution.
2. Simulate the ensemble of of reservoir forward in time through a
part of the historical period for which data is available.
3. Load the results, compare with the observed data, update the
parameters and the state of reservoir by filtering out the most
inacurate results, and restart the forward simulations.
This recipe is quite complex technically, and in particular involves
the ability to read and write input and output files from the
reservoir simulator (i.e. ECLIPSE in the case of `libecl`), run simulations
with arbitrary external programs, plotting data and so on. This
implies that a quite significant technical machinery must be in place
before the EnKF algorithm as such can be utilizied. This in particular
applies to real industry reservoir models, where typically
imperfections of all kinds flourish.
Despite the fact that the initial motivation for creating `libecl` was to
be able to use the EnKF algorithm for history matching, `libecl` is
currently more used with the Ensemble Smoother and also purely as a
workflow manager, i.e. herding a large collection of reservoir models
through the required simulations steps.
## 2. ECLIPSE Utilities
`libecl` has a quite large amount of code devoted to reading and writing
the ECLIPSE output files (grid/rft/restart/init/summary). In addition,
there is also reasonable support for reading and writing the grdecl
input files, but there is no general .DATA file parser. The ability to
read and write ECLIPSE output files is valuable in many reservoir
applications, and it is possible to only build and use the libecl
(with support libraries) library for working with ECLIPSE files. In
fact, the default build setup is to only build the ECLIPSE related
library and utilities. This part of the `libecl` distribution can also be
built on Windows with Visual Studio (albeit with maaaany warnings) and
with MinGW.
## 3. Building `libecl`
CMake is the build system for `libecl`. The top level CMakeLists.txt file
is located in the top level directory of the repository, and this
CMakeLists.txt file includes individual CMakeLists.txt files for the
different libraries.
Building with CMake is performed like this:
1. Create a build directory, this can in principle be anywhere in the
filesystem. One level above the toplevel source directory is a practical choice.
2. Go to the build directory and invoke the command:
```
ccmake <path/to/directory/containing/CMakeLists.txt>
```
Go through several 'configure' steps with CMake and generate native build files.
3. Exit ccmake and invoke the native build system, i.e. ordinarily 'make' on
Linux.
4. Subsequent builds can be performed using just the native make command, as in
step 3.
### 3.1 CMake settings you might want to adjust
The main setting you should adjust is `BUILD_ERT` which is default to
`OFF`, i.e. by default only the ECLIPSE related utilities will be
built. The build system has numerous configurations checks; the
ECLIPSE utilities should build on Windows, but to build all of `libecl` you
will need a Linux (Posix) system.
## 4. The code
The code is mainly a collection of libraries written in C.
### 4.1 The different libraries
The _provided libraries_ are:
* `libert_util`: This library is a collection of utilities of various sorts; if
C++ had been chosen as implementation language, most of these utilities could
probably be replaced by standard C++ classes.
* `libgeometry`: This is a very small geometry library; the main code is a small
implementantion of an alorithm to determine whether a point is inside a
polyhedron. The ECLIPSE library has some geometry related code which should be
moved here.
* `libwell`: This library will load well information from an ECLIPSE restart
file. This is mainly for the purpose of visualization of the existing wells,
and can not be used to update or model the well configuration.
* `libecl`: This library will read and (partly) write the various binary ECLIPSE
files, including `GRID/EGRID`, summary, `INIT`, restart and `RFT` files. There
is also support for reading an writing grdecl formatted files, but there is no
support for general parsing of the _ECLIPSE_ input format.
### 4.2 General structure
The code is written in C, but conventions give a 'scent of object
orientation'. Most of the code is uses the following conventions:
* Every file 'xxx' implements a data type 'xxx_type' - this naming convention is
quite strong.
* All the structure definitions are in the source files, i.e. external scopes
must access the data of a structure through accessor functions.
* All functions which operate on a type 'xxx_type' take a pointer to xxx_type as
their first argument, the structure closely resemble the 'self' argument used
when implementing Python classes.
* Memory management is manual; however there are some conventions:
* Functions allocating storage have _alloc_ as part of the name.
* For all functions xxx_alloc() which allocate memory, there
should be a matching xxx_free() function to discard the objects.
* Containers can optionally destroy their content if the content
is installed with a destructor.
* In `libert_util/src/type_macros.h` there is a macro based
'type-system' which is used to runtime check casts of (void *).
### 4.3 Python wrappers
Some of the code, in particular the ECLIPSE related functionality, has
been wrapped for usage in Python. Using these wrappers, it is quite
easy work with ECLIPSE files. The python wrappers are quite well
documented both in the directory python/docs and in the Python classes
themselves.
## 5. Tests
The `libecl` codebase has a small but increasing test coverage. The tests
are typically located in a per-library subdirectory tests/. The test
framework is based on ctest which basically works like this:
1. In the CMakeLists.txt file testing is enabled with `ENABLE_TESTING()`.
2. Tests are added with:
```python
add_test( test_name test_executable arg1 arg2 arg3 ... )
```
If the executable exits with status 0 the test has passed,
otherwise it has failed. The executable run by the test can
typically be an executable built as part of the solution, but can
in principle be an arbitrary executable like a dedicated test
runner or e.g. the Python interpreter.
### 5.1 Testing of C code
The main part of the testing infrastructure are small C applications
which are added like this:
```
add_executable( test_exe test_source.c )
target_link_libraries( test_exe lib )
add_test( test_name ${EXECUTABLE_OUTPUT_PATH}/test_exe commandline_arg1 commandline_arg2 )
```
Where the first two lines create the test executable in the normal
way, and the last line adds it as a test.
### 5.2 Testing of Python Code
In python/test there are several files with Python tests, these files
are executable files and they are invoked directly from the command
line. A limited number of the tests have been integrated in the ctest
system.
### 5.3 Test names
The tests in the cmake build system follow the naming convention of
the library regarding the functionality which they are testing: For
example, all tests for the libecl library use a name starting with
'ecl' and all tests for the tests for the config library are prefixed
by 'config'. The ctest options -R and -E can be used to include and
exclude tests based on their name
```
ctest -R ecl # Run all tests containing the regular expression 'ecl'
ctest -E ecl # Run all tests NOT containing the regular expression 'ecl'
```
### 5.4 Test labels
Using the cmake set_property() function it is possible to assign
labels to the test, and the -L and -LE options to ctest can be used to
limit which tests to run. A test can only have one label; in the
current ctest setup different labels are combined into one composite
label with a ":" separator, e.g.
```
set_property( TEST test_xxx PROPERTY LABELS StatoilData:Python)
```
will set the 'StatoilData' and 'Python' properties on test_xxx. The
labels currently available in the `libecl` test setup are:
StatoilData: This implies that the test makes use of Statoil
internal data. If you are work for the Bergen office of Statoil,
you can read the the file test-data/README for instructions on
how to make this data available.
If you are not for Statoil in Bergen, you must pass the option:
"-EL StatoilData" to ctest to skip all the tests which require
Statoil internal data.
StatoilBuild: There is one python test which makes use of Statoil
internal configuration data, this test is labeled with
StatoilBuild. If you want to run this test, you must set the
cmake option ECL_LOCAL_TARGET to point to a file which contains
these local configuration settings, e.g. where the ECLIPSE binary
is installed.
Python: This label is used to indicate that the test uses Python.
LSF: This labels indicates that the test needs a working LSF
environment to run.
### 5.5 ctest examples
```
ctest -L Statoil # Run all tests labeled with Statoil - both
# StatoilData and StatoilBuild
ctest -EL "Statoil|LSF" # Exclude all tests labeled with Statoil or LSF.
```

View File

@@ -1,85 +0,0 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'bcp.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.
*/
#include <util.h>
#include <block_fs.h>
#include <vector.h>
#include <signal.h>
#include <msg.h>
static void install_SIGNALS(void) {
signal(SIGSEGV , util_abort_signal); /* Segmentation violation, i.e. overwriting memory ... */
signal(SIGINT , util_abort_signal); /* Control C */
signal(SIGTERM , util_abort_signal); /* If killing the program with SIGTERM (the default kill signal) you will get a backtrace. Killing with SIGKILL (-9) will not give a backtrace.*/
}
static void usage() {
printf("Usage: \n\n");
printf("bcp src.mnt target.mnt file \n");
exit(1);
}
int main(int argc , char ** argv) {
install_SIGNALS();
if (argc < 4)
usage();
{
const char * src_mount = argv[1];
const char * target_mount = argv[2];
if (block_fs_is_mount(src_mount)) {
const char * pattern = NULL;
int iarg;
for (iarg = 3; iarg < argc; iarg++) {
if (argv[iarg][0] == '-') {
/** OK - this is an option .. */
}
else pattern = argv[iarg];
}
{
block_fs_type * src_fs = block_fs_mount(src_mount , 1 , 0 , 1 , 0 , false , true );
block_fs_type * target_fs = block_fs_mount(target_mount , 1 , 0 , 1 , 0 , false , false );
vector_type * files = block_fs_alloc_filelist( src_fs , pattern , NO_SORT , false );
buffer_type * buffer = buffer_alloc( 1024 );
{
int i;
msg_type * msg = msg_alloc("Copying :" , false);
msg_show( msg );
for (i=0; i < vector_get_size( files ); i++) {
const user_file_node_type * node = vector_iget_const( files , i );
const char * filename = user_file_node_get_filename( node );
msg_update( msg , filename );
block_fs_fread_realloc_buffer( src_fs , filename , buffer );
block_fs_fwrite_buffer( target_fs , filename , buffer );
}
msg_free( msg , true );
}
buffer_free( buffer );
vector_free( files );
block_fs_close( target_fs , true);
block_fs_close( src_fs , false );
}
} else
fprintf(stderr,"The files:%s/%s does not seem to be a block_fs mount files.\n" , src_mount , target_mount);
}
}

View File

@@ -1,100 +0,0 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'bfs_extract.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.
*/
#include <util.h>
#include <block_fs.h>
#include <vector.h>
#include <signal.h>
#include <msg.h>
/*****************************************************************/
/*
This program is used to extract individual files from a block_fs
file.
*/
void install_SIGNALS(void) {
signal(SIGSEGV , util_abort_signal); /* Segmentation violation, i.e. overwriting memory ... */
signal(SIGINT , util_abort_signal); /* Control C */
signal(SIGTERM , util_abort_signal); /* If killing the enkf program with SIGTERM (the default kill signal) you will get a backtrace. Killing with SIGKILL (-9) will not give a backtrace.*/
}
static void usage() {
fprintf(stderr,"\nThis program is used to extract individual files from a block_fs\n");
fprintf(stderr,"file. The arguments to the program are:\n");
fprintf(stderr,"\n");
fprintf(stderr," 1. The block_fs mount file.\n");
fprintf(stderr," 2. The name of directory (need not exist) where the extracted files will be put.\n");
fprintf(stderr," 3. A list of files to extract - this can contain wildcards, but they MUST be \n");
fprintf(stderr," quoted to avoid expansion by the shell.\n");
fprintf(stderr,"\n");
fprintf(stderr,"Example:\n\n");
fprintf(stderr," bash%% bfs_extract block_fs_file.mnt DOGFolder \'DOG*\'\n\n");
fprintf(stderr,"This will extract all files starting with \'DOG\' to folder \'DOGFolder\'.\n\n");
exit(1);
}
int main(int argc , char ** argv) {
install_SIGNALS();
if (argc < 3)
usage();
{
const char * mount_file = argv[1];
if (block_fs_is_mount(mount_file)) {
const char * target_path = argv[2];
int iarg;
if (!util_is_directory( target_path )) {
if (util_file_exists( target_path ))
util_exit("The target:%s already exists - but it is not a directory.\n");
else
util_make_path( target_path );
}
{
block_fs_type * block_fs = block_fs_mount(mount_file , 1 , 0 , 1 , 0 , false , true );
buffer_type * buffer = buffer_alloc(1024);
msg_type * msg = msg_alloc("Extracting: " , false);
msg_show( msg );
for (iarg = 3; iarg < argc; iarg++) {
vector_type * files = block_fs_alloc_filelist( block_fs , argv[iarg] , NO_SORT , false );
{
int i;
for (i=0; i < vector_get_size( files ); i++) {
const user_file_node_type * node = vector_iget_const( files , i );
const char * filename = user_file_node_get_filename( node );
const char * target_file = util_alloc_filename( target_path , filename , NULL );
msg_update( msg , filename );
block_fs_fread_realloc_buffer( block_fs , filename , buffer );
buffer_store( buffer , target_file );
}
}
vector_free( files );
}
block_fs_close( block_fs , false );
msg_free( msg , true );
}
} else
fprintf(stderr,"The file:%s does not seem to be a block_fs mount file.\n" , mount_file);
}
}

View File

@@ -1,221 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <util.h>
#include <block_fs.h>
#include <hash.h>
typedef enum {
WRITE_FILE = 1,
DELETE_FILE = 2,
CHECK = 3,
ROTATE = 4
} test_action_enum;
#define WRITE_FILE_STRING "WRITE_FILE"
#define DELETE_FILE_STRING "DELETE_FILE"
#define CHECK_STRING "CHECK"
#define ROATATE_STRING "ROTATE"
typedef struct {
test_action_enum action;
char * filename;
int length;
} action_node_type;
action_node_type * action_node_alloc_new() {
action_node_type * node = util_malloc( sizeof * node );
node->filename = NULL;
return node;
}
void action_node_free(action_node_type * node) {
util_safe_free( node->filename );
free( node );
}
void action_node_update(action_node_type * node, test_action_enum action , char * filename) {
util_safe_free( node->filename );
node->filename = filename; /* Node takes ownership of filename. */
node->action = action;
}
void apply_delete_file( const action_node_type * node , block_fs_type * fs , const char * file_path) {
if (block_fs_has_file( fs , node->filename)) {
char * filename = util_alloc_filename( file_path , node->filename , NULL );
block_fs_unlink_file( fs , node->filename );
unlink( filename );
free( filename );
}
}
void apply_check( block_fs_type * fs , const char * file_path ) {
char * buffer1 = NULL;
char * buffer2 = NULL;
int current_size = 0;
vector_type * files = block_fs_alloc_filelist( fs , NULL , NO_SORT , false );
int i;
for (i=0; i < vector_get_size( files ); i++) {
const user_file_node_type * node = vector_iget_const( files , i );
int size = user_file_node_get_data_size( node );
if (size > current_size) {
current_size = size;
buffer1 = util_realloc( buffer1 , current_size );
buffer2 = util_realloc( buffer2 , current_size );
}
block_fs_fread_file( fs , user_file_node_get_filename( node ) , buffer1 );
{
char * filename = util_alloc_filename( file_path , user_file_node_get_filename( node ) , NULL);
FILE * stream = util_fopen( filename , "r");
util_fread( buffer2 , 1 , size , stream , __func__);
fclose( stream );
free( filename );
}
if (memcmp( buffer1 , buffer2 , size ) != 0)
fprintf(stderr,"Fatal error ..\n");
}
vector_free( files );
free( buffer1 );
free( buffer2 );
printf("CHeck OK \n");
}
void apply_write_file( const action_node_type * node , block_fs_type * fs , const char * file_path) {
const int short_min = 128;
const int short_max = 256;
const int long_min = 4096;
const int long_max = 32000;
const double p_short = 0.75;
int length;
{
int min,max;
double R = rand() * 1.0 / RAND_MAX;
if (R < p_short) {
min = short_min;
max = short_max;
} else {
min = long_min;
max = long_max;
}
length = min + (rand() % (max - min + 1));
}
{
char * buffer = util_malloc( length * sizeof * buffer );
int i;
for (i=0; i < length; i++)
buffer[i] = rand() % 256;
block_fs_fwrite_file( fs , node->filename , buffer , length);
{
char * filename = util_alloc_filename( file_path , node->filename , NULL );
FILE * stream = util_fopen( filename , "w");
util_fwrite( buffer , 1 , length , stream , __func__ );
fclose( stream );
free(filename);
}
free( buffer );
}
}
void apply( const action_node_type ** action_list , int action_length, block_fs_type * fs , const char * file_path) {
int i;
for (i=0; i < action_length; i++) {
const action_node_type * node = action_list[i];
switch( node->action) {
case WRITE_FILE:
apply_write_file( node , fs , file_path );
break;
case DELETE_FILE:
apply_delete_file( node , fs , file_path );
break;
case CHECK:
apply_check( fs , file_path );
break;
case ROTATE:
block_fs_rotate( fs , 0.00 );
break;
default:
util_abort("Unrecognized enum value:%d \n", node->action );
}
}
}
int main(int argc, char ** argv) {
const char * test_path = "/tmp/block_fs";
const char * file_fmt = "file_%04d";
char * file_path = util_alloc_filename( test_path , "files" , NULL );
char * test_mnt = util_alloc_filename( test_path , "FORECAST" , "mnt");
char * test_log = util_alloc_filename( test_path , "test" , "log");
const int test_run = 10;
const int block_size = 1000;
const int max_files = 1000;
const int fs_block_size = 32;
const int cache_size = 2048;
const float frag_limit = 0.25;
const int fsync_interval = 100;
const bool preload = false;
int run = 0;
block_fs_type * block_fs = block_fs_mount( test_mnt , fs_block_size , cache_size , frag_limit , fsync_interval , preload , false );
action_node_type ** action_list = util_malloc( block_size * sizeof * action_list );
{
int i;
for (i=0; i < block_size; i++) {
action_list[i] = action_node_alloc_new( );
}
}
while ( run < test_run) {
int action_nr = 0;
run++;
while (action_nr < (block_size - 2)) {
char * filename = NULL;
int R = rand() % 3;
if (R == 0) {
/* Delete file */
filename = util_alloc_sprintf( file_fmt , rand() % max_files );
action_node_update( action_list[ action_nr ] , DELETE_FILE , filename );
} else {
/* Create file */
filename = util_alloc_sprintf( file_fmt , rand() % max_files );
action_node_update( action_list[ action_nr ] , WRITE_FILE , filename );
}
action_nr++;
}
action_node_update( action_list[ block_size - 2] , ROTATE , NULL);
action_node_update( action_list[ block_size - 1] , CHECK , NULL);
apply( (const action_node_type **) action_list , block_size , block_fs , file_path );
//fprintf_log( log_stream , action_list , block_size );
printf("*"); fflush( stdout );
}
{
int i;
for (i=0; i < block_size; i++)
action_node_free( action_list[i] );
}
free( action_list );
block_fs_close( block_fs , true);
free( file_path );
free( test_mnt );
free( test_log );
}

View File

@@ -1,77 +0,0 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'bls.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.
*/
#include <signal.h>
#include <ert/util/util.h>
#include <ert/util/block_fs.h>
#include <ert/util/vector.h>
void install_SIGNALS(void) {
signal(SIGSEGV , util_abort_signal); /* Segmentation violation, i.e. overwriting memory ... */
signal(SIGINT , util_abort_signal); /* Control C */
signal(SIGTERM , util_abort_signal); /* If killing the enkf program with SIGTERM (the default kill signal) you will get a backtrace. Killing with SIGKILL (-9) will not give a backtrace.*/
}
static int usage( void ) {
fprintf(stderr,"\n");
fprintf(stderr,"Usage:\n\n");
fprintf(stderr," bash%% bls BLOCK_FILE.mnt <pattern>\n\n");
fprintf(stderr,"Will list all elements in BLOCK_FILE matching pattern - remember to quote wildcards.\n");
exit(1);
}
int main(int argc , char ** argv) {
install_SIGNALS();
if (argc == 1)
usage();
{
const char * mount_file = argv[1];
if (block_fs_is_mount(mount_file)) {
block_fs_sort_type sort_mode = OFFSET_SORT;
const char * pattern = NULL;
int iarg;
for (iarg = 2; iarg < argc; iarg++) {
if (argv[iarg][0] == '-') {
/** OK - this is an option .. */
}
else
pattern = argv[iarg];
}
{
block_fs_type * block_fs = block_fs_mount(mount_file , 1 , 0 , 1 , 0 , false , true , false);
vector_type * files = block_fs_alloc_filelist( block_fs , pattern , sort_mode , false );
{
int i;
for (i=0; i < vector_get_size( files ); i++) {
const user_file_node_type * node = vector_iget_const( files , i );
printf("%-40s %10d %ld \n",user_file_node_get_filename( node ), user_file_node_get_data_size( node ) , user_file_node_get_node_offset( node ));
}
}
vector_free( files );
block_fs_close( block_fs , false );
}
} else
fprintf(stderr,"The file:%s does not seem to be a block_fs mount file.\n" , mount_file);
}
}

View File

@@ -1,73 +0,0 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'brm.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.
*/
#include <util.h>
#include <block_fs.h>
#include <vector.h>
#include <signal.h>
#include <msg.h>
void install_SIGNALS(void) {
signal(SIGSEGV , util_abort_signal); /* Segmentation violation, i.e. overwriting memory ... */
signal(SIGINT , util_abort_signal); /* Control C */
signal(SIGTERM , util_abort_signal); /* If killing the enkf program with SIGTERM (the default kill signal) you will get a backtrace. Killing with SIGKILL (-9) will not give a backtrace.*/
}
int main(int argc , char ** argv) {
install_SIGNALS();
const char * mount_file = argv[1];
if (block_fs_is_mount(mount_file)) {
block_fs_sort_type sort_mode = OFFSET_SORT;
const char * pattern = NULL;
int iarg;
for (iarg = 2; iarg < argc; iarg++) {
if (argv[iarg][0] == '-') {
/** OK - this is an option .. */
}
else pattern = argv[iarg];
}
{
block_fs_type * block_fs = block_fs_mount(mount_file , 1 , 0 , 1 , 0 , false , false );
vector_type * files = block_fs_alloc_filelist( block_fs , pattern , sort_mode , false );
{
int i;
msg_type * msg = msg_alloc("Deleting file: " , false);
msg_show( msg );
//for (i=0; i < vector_get_size( files ); i++) {
// const user_file_node_type * node = vector_iget_const( files , i );
// printf("%-40s %10d %ld \n",user_file_node_get_filename( node ), user_file_node_get_data_size( node ) , user_file_node_get_node_offset( node ));
//}
for (i=0; i < vector_get_size( files ); i++) {
const user_file_node_type * node = vector_iget_const( files , i );
msg_update( msg , user_file_node_get_filename( node ) );
block_fs_unlink_file( block_fs , user_file_node_get_filename( node ));
}
msg_free( msg , true );
printf("Final fragmentation: %5.2f \n", block_fs_get_fragmentation( block_fs ));
}
vector_free( files );
block_fs_close( block_fs , false );
}
} else
fprintf(stderr,"The file:%s does not seem to be a block_fs mount file.\n" , mount_file);
}

View File

@@ -1,41 +0,0 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'brot.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.
*/
#include <util.h>
#include <block_fs.h>
#include <vector.h>
#include <signal.h>
#include <msg.h>
void install_SIGNALS(void) {
signal(SIGSEGV , util_abort_signal); /* Segmentation violation, i.e. overwriting memory ... */
signal(SIGINT , util_abort_signal); /* Control C */
signal(SIGTERM , util_abort_signal); /* If killing the enkf program with SIGTERM (the default kill signal) you will get a backtrace. Killing with SIGKILL (-9) will not give a backtrace.*/
}
int main(int argc , char ** argv) {
install_SIGNALS();
const char * mount_file = argv[1];
if (block_fs_is_mount(mount_file)) {
block_fs_type * block_fs = block_fs_mount(mount_file , 1 , 0 , 1 , 0 , false , false );
block_fs_rotate( block_fs , 0.00 );
block_fs_close( block_fs , false );
}
}

View File

@@ -1,6 +1,5 @@
find_package(Sphinx REQUIRED)
if (SPHINX_FOUND)
set( ERT_DOC_INSTALL_PATH "" CACHE PATH "Absolute path to install documentation *in addition* to $PREFIX/documentation")
set( ERT_DOC_EXTERNAL_ROOT "" CACHE PATH "Path to site local ERT documentation")
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/doc-src")
@@ -21,7 +20,7 @@ if (SPHINX_FOUND)
if (BUILD_PYTHON)
add_custom_target(api-doc ALL
COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_SOURCE_DIR}/code" "${PROJECT_BINARY_DIR}/doc-src/code"
COMMAND sphinx-apidoc -e -o doc-src/API/python ${PROJECT_BINARY_DIR}/${PYTHON_INSTALL_PREFIX}
COMMAND sphinx-apidoc -e -o doc-src/API/python/ecl ${PROJECT_BINARY_DIR}/${PYTHON_INSTALL_PREFIX}
DEPENDS ecl
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
endif()

View File

@@ -1,3 +0,0 @@
The ert.config package
======================

View File

@@ -1,2 +0,0 @@
The ert.enkf package
====================

View File

@@ -5,11 +5,9 @@ The ert packages
:maxdepth: 1
util/index.rst
config/index.rst
eclipse/index.rst
well/index.rst
geometry/index.rst
enkf/index.rst
Currently only the package targeted at working with Eclipse files,

View File

@@ -3,7 +3,7 @@ project(libecl-ecl C CXX)
if (HAVE_PTHREAD)
# The block_fs filesystem is so heavily dependant on pthreads that it is
# not built if de not have pthreads.
list(APPEND opt_srcs util/thread_pool.c util/block_fs.c)
list(APPEND opt_srcs util/thread_pool.c)
endif ()
if (LAPACK_FOUND)
@@ -38,10 +38,6 @@ if (ERT_HAVE_LOCKF)
list(APPEND opt_srcs util/util_lockf.c)
endif ()
if (ERT_HAVE_REGEXP)
list(APPEND opt_srcs util/template_loop.c)
endif ()
if (ERT_HAVE_UNISTD)
list(APPEND opt_srcs util/path_stack.c)
endif ()
@@ -50,8 +46,17 @@ if (MSVC)
configure_file(include/ert/util/msvc_stdbool.h ert/util/stdbool.h)
endif ()
foreach (type int double bool long time_t size_t float)
foreach (type int double long time_t float)
set(TYPE ${type})
set(SIGNED_TYPE true)
configure_file(vector_template.h.in include/ert/util/${type}_vector.h)
configure_file(util/vector_template.c ${type}_vector.c)
list(APPEND opt_srcs ${CMAKE_CURRENT_BINARY_DIR}/${type}_vector.c)
endforeach ()
foreach (type bool size_t)
set(TYPE ${type})
set(SIGNED_TYPE false)
configure_file(vector_template.h.in include/ert/util/${type}_vector.h)
configure_file(util/vector_template.c ${type}_vector.c)
list(APPEND opt_srcs ${CMAKE_CURRENT_BINARY_DIR}/${type}_vector.c)
@@ -86,11 +91,11 @@ add_library(ecl util/rng.c
util/util_env.c
util/util_symlink.c
util/util_lfs.c
util/util_unlink.c
util/msg.c
util/arg_pack.c
util/path_fmt.c
util/menu.c
util/subst_list.c
util/subst_func.c
util/vector.c
util/parser.c
@@ -98,13 +103,12 @@ add_library(ecl util/rng.c
util/matrix.c
util/buffer.c
util/log.c
util/template.c
util/timer.c
util/time_interval.c
util/string_util.c
util/type_vector_functions.c
util/ui_return.c
util/ert_version.c
util/ecl_version.c
util/struct_vector.c
util/perm_vector.c
util/test_util.c
@@ -191,9 +195,9 @@ target_include_directories(ecl
target_compile_definitions(ecl PRIVATE
-DGIT_COMMIT=${GIT_COMMIT}
-DGIT_COMMIT_SHORT=${GIT_COMMIT_SHORT}
-DERT_VERSION_MAJOR=${ERT_VERSION_MAJOR}
-DERT_VERSION_MINOR=${ERT_VERSION_MINOR}
-DERT_VERSION_MICRO=${ERT_VERSION_MICRO}
-DECL_VERSION_MAJOR=${ECL_VERSION_MAJOR}
-DECL_VERSION_MINOR=${ECL_VERSION_MINOR}
-DECL_VERSION_MICRO=${ECL_VERSION_MICRO}
)
target_compile_options(ecl PUBLIC ${pthreadarg})
@@ -208,35 +212,33 @@ if (ERT_USE_OPENMP)
endif ()
set_target_properties(ecl PROPERTIES
VERSION ${ERT_VERSION_MAJOR}.${ERT_VERSION_MINOR}
SOVERSION ${ERT_VERSION_MAJOR})
VERSION ${ECL_VERSION_MAJOR}.${ECL_VERSION_MINOR}
SOVERSION ${ECL_VERSION_MAJOR})
if (INSTALL_ERT)
install(TARGETS ecl
EXPORT ecl-config
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(TARGETS ecl
EXPORT ecl-config
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(DIRECTORY include/
DESTINATION include
PATTERN *.h
)
install(DIRECTORY include/
DESTINATION include
PATTERN *.hpp EXCLUDE
)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/
DESTINATION include
PATTERN *.h
)
if (ERT_BUILD_CXX)
install(DIRECTORY include/
DESTINATION include
PATTERN *.h
)
install(DIRECTORY include/
DESTINATION include
PATTERN *.hpp EXCLUDE
)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/
DESTINATION include
PATTERN *.h
)
if (ERT_BUILD_CXX)
install(DIRECTORY include/
DESTINATION include
PATTERN *.hpp
)
endif ()
endif()
PATTERN *.hpp
)
endif ()
if (NOT BUILD_TESTS)
return ()
@@ -265,7 +267,6 @@ foreach (name ert_util_alloc_file_components
ert_util_stringlist_test
ert_util_string_util
ert_util_strstr_int_format
ert_util_subst_list
ert_util_time_interval
ert_util_type_vector_functions
ert_util_ui_return
@@ -278,6 +279,11 @@ foreach (name ert_util_alloc_file_components
add_test(NAME ${name} COMMAND ${name})
endforeach ()
add_executable(ecl_smspec_node ecl/tests/ecl_smspec_node.c)
target_link_libraries( ecl_smspec_node ecl)
add_test(NAME ecl_smspec_node COMMAND ecl_smspec_node)
add_executable(ert_util_work_area util/tests/ert_util_work_area.c)
target_link_libraries(ert_util_work_area ecl)
add_test(NAME ert_util_work_area
@@ -336,10 +342,6 @@ if (HAVE_BACKTRACE)
endif()
if (HAVE_UTIL_ABORT_INTERCEPT)
add_executable(ert_util_block_fs util/tests/ert_util_block_fs.c)
target_link_libraries(ert_util_block_fs ecl)
add_test(NAME ert_util_block_fs COMMAND ert_util_block_fs)
add_executable(ert_util_struct_vector util/tests/ert_util_struct_vector.c)
target_link_libraries(ert_util_struct_vector ecl)
add_test(NAME ert_util_struct_vector COMMAND ert_util_struct_vector)
@@ -379,6 +381,8 @@ foreach (name ecl_alloc_cpgrid
ecl_nnc_info_test
ecl_nnc_vector
ecl_rft_cell
ecl_file_view
test_ecl_file_index
ecl_rst_file
ecl_sum_writer
ecl_util_make_date_no_shift

View File

@@ -28,6 +28,8 @@
#cmakedefine HAVE_CHMOD
#cmakedefine HAVE_MODE_T
#cmakedefine HAVE_CXX_SHARED_PTR
#cmakedefine HAVE_POSIX_UNLINK
#cmakedefine HAVE_WINDOWS_UNLINK
#cmakedefine HAVE_WINDOWS_GET_TEMP_PATH

View File

@@ -21,6 +21,10 @@ namespace ERT {
return *this;
}
int smspec_node::cmp( const smspec_node& node1, const smspec_node& node2) {
return smspec_node_cmp( node1.get() , node2.get() );
}
static const int dummy_dims[ 3 ] = { -1, -1, -1 };
const auto default_join = ":";

View File

@@ -569,8 +569,8 @@ void ecl_file_select_global( ecl_file_type * ecl_file ) {
*/
ecl_file_type * ecl_file_open( const char * filename , int flags) {
fortio_type * fortio;
static fortio_type * ecl_file_alloc_fortio(const char * filename, int flags) {
fortio_type * fortio = NULL;
bool fmt_file;
ecl_util_fmt_file( filename , &fmt_file);
@@ -580,6 +580,13 @@ ecl_file_type * ecl_file_open( const char * filename , int flags) {
else
fortio = fortio_open_reader( filename , fmt_file , ECL_ENDIAN_FLIP);
return fortio;
}
ecl_file_type * ecl_file_open( const char * filename , int flags) {
fortio_type * fortio = ecl_file_alloc_fortio(filename, flags);
if (fortio) {
ecl_file_type * ecl_file = ecl_file_alloc_empty( flags );
ecl_file->fortio = fortio;
@@ -636,7 +643,9 @@ void ecl_file_close(ecl_file_type * ecl_file) {
if (ecl_file->fortio != NULL)
fortio_fclose( ecl_file->fortio );
ecl_file_view_free( ecl_file->global_view );
if (ecl_file->global_view)
ecl_file_view_free( ecl_file->global_view );
inv_map_free( ecl_file->inv_view );
vector_free( ecl_file->map_stack );
free( ecl_file );
@@ -992,3 +1001,89 @@ static ecl_file_type * ecl_file_iopen_rstblock__( const char * filename , int se
ecl_file_type * ecl_file_iopen_rstblock( const char * filename , int seqnum_index , int flags) {
return ecl_file_iopen_rstblock__(filename , seqnum_index , flags );
}
static bool ecl_file_index_valid0(const char * file_name, const char * index_file_name) {
if ( !util_file_exists( file_name ))
return false;
if (!util_file_exists (index_file_name))
return false;
if (util_file_difftime( file_name , index_file_name) > 0)
return false;
return true;
}
static bool ecl_file_index_valid1(const char * file_name, FILE * stream ) {
bool name_equal;
char * source_file = util_fread_alloc_string(stream);
char * input_name = util_split_alloc_filename( file_name );
name_equal = util_string_equal( source_file , input_name );
free( source_file );
free( input_name );
return name_equal;
}
bool ecl_file_index_valid(const char * file_name, const char * index_file_name) {
if (!ecl_file_index_valid0( file_name , index_file_name))
return false;
bool valid = false;
FILE * stream = fopen(index_file_name, "rb");
if (stream) {
valid = ecl_file_index_valid1( file_name , stream );
fclose( stream );
}
return valid;
}
bool ecl_file_write_index( const ecl_file_type * ecl_file , const char * index_filename) {
FILE * ostream = fopen(index_filename, "wb");
if (!ostream)
return false;
{
char * filename = util_split_alloc_filename( fortio_filename_ref(ecl_file->fortio));
util_fwrite_string( filename , ostream );
free( filename );
}
ecl_file_view_write_index( ecl_file->global_view , ostream );
fclose( ostream );
return true;
}
ecl_file_type * ecl_file_fast_open(const char * file_name, const char * index_file_name, int flags) {
if ( !ecl_file_index_valid0(file_name, index_file_name) )
return NULL;
FILE * istream = fopen(index_file_name, "rb");
if (!istream)
return NULL;
ecl_file_type * ecl_file = NULL;
if (ecl_file_index_valid1( file_name, istream)) {
fortio_type * fortio = ecl_file_alloc_fortio(file_name, flags);
if (fortio) {
ecl_file = ecl_file_alloc_empty( flags );
ecl_file->fortio = fortio;
ecl_file->global_view = ecl_file_view_fread_alloc( ecl_file->fortio , &ecl_file->flags , ecl_file->inv_view , istream );
if (ecl_file->global_view) {
ecl_file_select_global( ecl_file );
if (ecl_file_view_check_flags( ecl_file->flags , ECL_FILE_CLOSE_STREAM))
fortio_fclose_stream( ecl_file->fortio );
}
else {
ecl_file_close( ecl_file );
ecl_file = NULL;
}
}
}
fclose(istream);
return ecl_file;
}

View File

@@ -135,7 +135,7 @@ UTIL_IS_INSTANCE_FUNCTION( ecl_file_kw , ECL_FILE_KW_TYPE_ID )
static ecl_file_kw_type * ecl_file_kw_alloc__( const char * header , ecl_data_type data_type , int size , offset_type offset) {
ecl_file_kw_type * ecl_file_kw_alloc0( const char * header , ecl_data_type data_type , int size , offset_type offset) {
ecl_file_kw_type * file_kw = util_malloc( sizeof * file_kw );
UTIL_TYPE_ID_INIT( file_kw , ECL_FILE_KW_TYPE_ID );
@@ -161,7 +161,7 @@ static ecl_file_kw_type * ecl_file_kw_alloc__( const char * header , ecl_data_ty
*/
ecl_file_kw_type * ecl_file_kw_alloc( const ecl_kw_type * ecl_kw , offset_type offset ) {
return ecl_file_kw_alloc__( ecl_kw_get_header( ecl_kw ) , ecl_kw_get_data_type( ecl_kw ) , ecl_kw_get_size( ecl_kw ) , offset );
return ecl_file_kw_alloc0( ecl_kw_get_header( ecl_kw ) , ecl_kw_get_data_type( ecl_kw ) , ecl_kw_get_size( ecl_kw ) , offset );
}
@@ -169,7 +169,7 @@ ecl_file_kw_type * ecl_file_kw_alloc( const ecl_kw_type * ecl_kw , offset_type o
Does NOT copy the kw pointer which must be reloaded.
*/
ecl_file_kw_type * ecl_file_kw_alloc_copy( const ecl_file_kw_type * src ) {
return ecl_file_kw_alloc__( src->header , ecl_file_kw_get_data_type(src) , src->kw_size , src->file_offset );
return ecl_file_kw_alloc0( src->header , ecl_file_kw_get_data_type(src) , src->kw_size , src->file_offset );
}
@@ -191,6 +191,19 @@ void ecl_file_kw_free__( void * arg ) {
}
bool ecl_file_kw_equal( const ecl_file_kw_type * kw1 , const ecl_file_kw_type * kw2)
{
if (kw1->file_offset != kw2->file_offset)
return false;
if (kw1->kw_size != kw2->kw_size)
return false;
if (!ecl_type_is_equal( kw1->data_type, kw2->data_type))
return false;
return util_string_equal( kw1->header , kw2->header );
}
static void ecl_file_kw_assert_kw( const ecl_file_kw_type * file_kw ) {
if(!ecl_type_is_equal(
@@ -273,7 +286,7 @@ void ecl_file_kw_replace_kw( ecl_file_kw_type * file_kw , fortio_type * target ,
ecl_kw_get_data_type(new_kw)
))
util_abort("%s: sorry type mismatch between in-file keyword and new keyword \n",__func__);
if((file_kw->kw_size == ecl_kw_get_size( new_kw )))
if(file_kw->kw_size != ecl_kw_get_size(new_kw))
util_abort("%s: sorry size mismatch between in-file keyword and new keyword \n",__func__);
if (file_kw->kw != NULL)
@@ -323,4 +336,89 @@ void ecl_file_kw_inplace_fwrite( ecl_file_kw_type * file_kw , fortio_type * fort
}
void ecl_file_kw_fwrite( const ecl_file_kw_type * file_kw , FILE * stream ) {
int header_length = strlen( file_kw->header );
for (int i=0; i < ECL_STRING8_LENGTH; i++) {
if (i < header_length)
fputc( file_kw->header[i], stream );
else
fputc( ' ' , stream );
}
util_fwrite_int( file_kw->kw_size , stream );
util_fwrite_offset( file_kw->file_offset , stream );
util_fwrite_int( ecl_type_get_type( file_kw->data_type ) , stream );
util_fwrite_size_t( ecl_type_get_sizeof_ctype_fortio( file_kw->data_type ) , stream );
}
ecl_file_kw_type ** ecl_file_kw_fread_alloc_multiple( FILE * stream , int num) {
size_t file_kw_size = ECL_STRING8_LENGTH + 2 * sizeof(int) + sizeof(offset_type) + sizeof(size_t);
size_t buffer_size = num * file_kw_size;
char * buffer = util_malloc( buffer_size * sizeof * buffer );
size_t num_read = fread( buffer, 1 , buffer_size , stream);
if (num_read != buffer_size) {
free( buffer );
return NULL;
}
{
ecl_file_kw_type ** kw_list = util_malloc( num * sizeof * kw_list );
for (int ikw = 0; ikw < num; ikw++) {
int buffer_offset = ikw * file_kw_size;
char header[ECL_STRING8_LENGTH + 1];
int kw_size;
offset_type file_offset;
ecl_type_enum ecl_type;
size_t type_size;
{
int index = 0;
while (true) {
if (buffer[index + buffer_offset] != ' ')
header[index] = buffer[index + buffer_offset];
else
break;
index++;
if (index == ECL_STRING8_LENGTH)
break;
}
header[index] = '\0';
buffer_offset += ECL_STRING8_LENGTH;
}
kw_size = *((int *) &buffer[ buffer_offset ]);
buffer_offset += sizeof kw_size;
file_offset = *((offset_type *) &buffer[ buffer_offset ]);
buffer_offset += sizeof file_offset;
ecl_type = *(( ecl_type_enum *) &buffer[ buffer_offset ]);
buffer_offset += sizeof ecl_type;
type_size = *((size_t *) &buffer[ buffer_offset ]);
buffer_offset += sizeof type_size;
kw_list[ikw] = ecl_file_kw_alloc0( header , ecl_type_create( ecl_type , type_size ), kw_size, file_offset );
}
free( buffer );
return kw_list;
}
}
ecl_file_kw_type * ecl_file_kw_fread_alloc( FILE * stream ) {
ecl_file_kw_type * file_kw = NULL;
ecl_file_kw_type ** multiple = ecl_file_kw_fread_alloc_multiple( stream , 1 );
if (multiple) {
file_kw = multiple[0];
free( multiple );
}
return file_kw;
}

View File

@@ -777,3 +777,35 @@ ecl_file_view_type * ecl_file_view_add_summary_view( ecl_file_view_type * file_v
void ecl_file_view_fclose_stream( ecl_file_view_type * file_view ) {
fortio_fclose_stream( file_view->fortio );
}
void ecl_file_view_write_index(const ecl_file_view_type * file_view, FILE * ostream) {
int size = ecl_file_view_get_size(file_view);
util_fwrite_int( size , ostream);
ecl_file_kw_type * file_kw;
for (int i = 0; i < size; i++) {
file_kw = ecl_file_view_iget_file_kw( file_view, i );
ecl_file_kw_fwrite( file_kw , ostream );
}
}
ecl_file_view_type * ecl_file_view_fread_alloc( fortio_type * fortio , int * flags , inv_map_type * inv_map, FILE * istream ) {
int index_size = util_fread_int(istream);
ecl_file_kw_type ** file_kw_list = ecl_file_kw_fread_alloc_multiple( istream, index_size);
if (file_kw_list) {
ecl_file_view_type * file_view = ecl_file_view_alloc( fortio , flags , inv_map , true );
for (int i=0; i < index_size; i++)
ecl_file_view_add_kw(file_view , file_kw_list[i]);
free(file_kw_list);
ecl_file_view_make_index( file_view );
return file_view;
}
else {
fprintf(stderr, "%s: error reading ecl_file_type index file.\n", __func__);
return NULL;
}
}

View File

@@ -6436,6 +6436,7 @@ ecl_kw_type * ecl_grid_alloc_gridhead_kw( int nx, int ny , int nz , int grid_nr)
ecl_kw_iset_int( gridhead_kw , GRIDHEAD_NX_INDEX , nx);
ecl_kw_iset_int( gridhead_kw , GRIDHEAD_NY_INDEX , ny);
ecl_kw_iset_int( gridhead_kw , GRIDHEAD_NZ_INDEX , nz);
ecl_kw_iset_int( gridhead_kw , GRIDHEAD_NUMRES_INDEX , 1);
ecl_kw_iset_int( gridhead_kw , GRIDHEAD_LGR_INDEX , grid_nr );
return gridhead_kw;
}

View File

@@ -850,9 +850,11 @@ void ecl_kw_iset_char_ptr( ecl_kw_type * ecl_kw , int index, const char * s) {
}
/**
* This function will verify that the given string is of approperiate length
* (0 <= lenght <= data_type.element_size). If so, the elements of @s will be
* written to the @ecl_kw string array starting at @index.
This function will verify that the given string is of approperiate
length (0 <= lenght <= data_type.element_size). If so, the elements
of @s will be written to the @ecl_kw string array starting at
@index. If the input string is shorter than the type length the
string will be padded with trailing spaces.
*/
void ecl_kw_iset_string_ptr( ecl_kw_type * ecl_kw, int index, const char * s) {
if(!ecl_type_is_alpha(ecl_kw_get_data_type(ecl_kw))) {
@@ -866,11 +868,18 @@ void ecl_kw_iset_string_ptr( ecl_kw_type * ecl_kw, int index, const char * s) {
if(input_len > type_len)
util_abort("%s: String of length %d cannot hold input string of length %d\n", __func__, type_len, input_len);
char * ecl_string = (char *) ecl_kw_iget_ptr(ecl_kw, index);
for(int i = 0; i < input_len; ++i)
ecl_string[i] = s[i];
{
char * ecl_string = (char *) ecl_kw_iget_ptr(ecl_kw, index);
int i;
ecl_string[input_len] = '\0';
for(i = 0; i < input_len; ++i)
ecl_string[i] = s[i];
for (i=input_len; i < type_len; ++i)
ecl_string[i] = ' ';
ecl_string[type_len] = '\0';
}
}

View File

@@ -88,49 +88,42 @@ static const char * ecl_nnc_data_get_str_kw(int kw_type, int grid1, int grid2) {
static ecl_kw_type * ecl_nnc_data_get_gl_kw( const ecl_file_view_type * init_file_view , const char * kw, int kw_type, int lgr_nr) {
ecl_kw_type * return_kw = NULL;
if(!kw)
return NULL;
if (kw != NULL)
if (lgr_nr == 0) {
if(ecl_file_view_has_kw(init_file_view, kw))
return_kw = ecl_file_view_iget_named_kw(init_file_view, kw, 0);
} else {
{
const int file_num_kw = ecl_file_view_get_size( init_file_view );
int global_kw_index = 0;
bool finished = false;
bool correct_lgrheadi = false;
int head_index = 0;
int steps = 0;
return ecl_file_view_iget_named_kw(init_file_view, kw, 0);
else
return NULL;
}
while(!finished){
ecl_kw_type * ecl_kw = ecl_file_view_iget_kw( init_file_view , global_kw_index );
const char *current_kw = ecl_kw_get_header(ecl_kw);
if (strcmp( LGRHEADI_KW , current_kw) == 0) {
if (ecl_kw_iget_int( ecl_kw , LGRHEADI_LGR_NR_INDEX) == lgr_nr) {
correct_lgrheadi = true;
head_index = global_kw_index;
}else{
correct_lgrheadi = false;
}
}
if(correct_lgrheadi) {
if (strcmp(kw, current_kw) == 0) {
steps = global_kw_index - head_index; /* This is to calculate who fare from lgrheadi we found the TRANGL/TRANNNC key word */
if (kw_type != TRANS_DATA || steps == 3 || steps == 4 || steps == 6) { /* We only support a file format where TRANNNC is 3 steps and TRANGL is 4 or 6 steps from LGRHEADI */
return_kw = ecl_kw;
finished = true;
break;
}
}
}
global_kw_index++;
if (global_kw_index == file_num_kw)
finished = true;
bool correct_lgrheadi = false;
const int file_num_kw = ecl_file_view_get_size(init_file_view);
for(int kw_index = 0, head_index = 0; kw_index < file_num_kw; ++kw_index) {
ecl_kw_type * ecl_kw = ecl_file_view_iget_kw(init_file_view, kw_index);
const char * current_kw = ecl_kw_get_header(ecl_kw);
if (strcmp(LGRHEADI_KW, current_kw) == 0) {
if (ecl_kw_iget_int(ecl_kw, LGRHEADI_LGR_NR_INDEX) == lgr_nr) {
correct_lgrheadi = true;
head_index = kw_index;
} else {
correct_lgrheadi = false;
}
}
if (correct_lgrheadi && strcmp(kw, current_kw) == 0) {
/* This is to calculate who fare from lgrheadi we found the TRANGL/TRANNNC key word */
int steps = kw_index - head_index;
/* We only support a file format where TRANNNC is 3 steps and TRANGL is 4 or 6 steps from LGRHEADI */
if (kw_type != TRANS_DATA || steps == 3 || steps == 4 || steps == 6) {
return ecl_kw;
}
}
}
return return_kw;
return NULL;
}
@@ -174,7 +167,7 @@ static ecl_kw_type * ecl_nnc_data_get_kw( const ecl_grid_type * grid, const ecl_
return NULL;
}
static void assert_correct_kw_count(ecl_kw_type * kw, char * function_name, bool check_kw_count, int correct_kw_count, int kw_count) {
static void assert_correct_kw_count(ecl_kw_type * kw, const char * function_name, bool check_kw_count, int correct_kw_count, int kw_count) {
if (check_kw_count & (correct_kw_count != kw_count))
util_abort("In function %s, reading kw: %s. %d != %d", function_name, ecl_kw_get_header(kw), correct_kw_count, kw_count);
}
@@ -269,10 +262,13 @@ const double * ecl_nnc_data_get_values( const ecl_nnc_data_type * data ) {
double ecl_nnc_data_iget_value(const ecl_nnc_data_type * data, int index) {
if (index < data->size)
return data->values[index];
else
util_abort("%s: index value:%d out range: [0,%d) \n",__func__ , index , data->size);
if (index >= data->size)
util_abort(
"%s: index value:%d out range: [0,%d) \n",
__func__ , index , data->size
);
return data->values[index];
}

View File

@@ -292,12 +292,14 @@ int * ecl_smspec_alloc_mapping( const ecl_smspec_type * self, const ecl_smspec_t
for (int i=0; i < ecl_smspec_num_nodes( self ); i++) {
const smspec_node_type * self_node = ecl_smspec_iget_node( self , i );
int self_index = smspec_node_get_params_index( self_node );
const char * key = smspec_node_get_gen_key1( self_node );
if (ecl_smspec_has_general_var( other , key)) {
const smspec_node_type * other_node = ecl_smspec_get_general_var_node( other , key);
int other_index = smspec_node_get_params_index(other_node);
mapping[ self_index ] = other_index;
if (smspec_node_is_valid( self_node )) {
int self_index = smspec_node_get_params_index( self_node );
const char * key = smspec_node_get_gen_key1( self_node );
if (ecl_smspec_has_general_var( other , key)) {
const smspec_node_type * other_node = ecl_smspec_get_general_var_node( other , key);
int other_index = smspec_node_get_params_index(other_node);
mapping[ self_index ] = other_index;
}
}
}
@@ -344,12 +346,15 @@ void ecl_smspec_lock( ecl_smspec_type * smspec ) {
static ecl_data_type get_wgnames_type(const ecl_smspec_type * smspec) {
size_t max_len = 0;
for(int i = 0; i < ecl_smspec_num_nodes(smspec); ++i) {
const char * name = smspec_node_get_wgname(ecl_smspec_iget_node(smspec, i));
if(name != NULL)
const smspec_node_type * node = ecl_smspec_iget_node(smspec, i);
if (smspec_node_is_valid( node )) {
const char * name = smspec_node_get_wgname( node );
if(name)
max_len = util_size_t_max(max_len, strlen(name));
}
}
return max_len <= 8 ? ECL_CHAR : ECL_STRING(max_len);
return max_len <= ECL_STRING8_LENGTH ? ECL_CHAR : ECL_STRING(max_len);
}
// DIMENS
@@ -364,9 +369,19 @@ static void ecl_smspec_fortio_fwrite( const ecl_smspec_type * smspec , fortio_ty
int num_nodes = ecl_smspec_num_nodes( smspec );
{
ecl_kw_type * restart_kw = ecl_kw_alloc( RESTART_KW , SUMMARY_RESTART_SIZE , ECL_CHAR );
int i;
for (i=0; i < SUMMARY_RESTART_SIZE; i++)
ecl_kw_iset_string8( restart_kw , i , "");
for (int i=0; i < SUMMARY_RESTART_SIZE; i++)
ecl_kw_iset_string8( restart_kw , i , "");
if (smspec->restart_case != NULL) {
int restart_case_len = strlen(smspec->restart_case);
int offset = 0;
for (int i = 0; i < SUMMARY_RESTART_SIZE ; i++) {
if (offset < restart_case_len)
ecl_kw_iset_string8( restart_kw , i , &smspec->restart_case[ offset ]);
offset += ECL_STRING8_LENGTH;
}
}
ecl_kw_fwrite( restart_kw , fortio );
ecl_kw_free( restart_kw );
@@ -435,7 +450,7 @@ static void ecl_smspec_fortio_fwrite( const ecl_smspec_type * smspec , fortio_ty
ecl_kw_iset_string8( units_kw , i , smspec_node_get_unit( smspec_node ));
{
const char * wgname = DUMMY_WELL;
if (smspec_node_get_wgname( smspec_node ) != NULL)
if (smspec_node_get_wgname( smspec_node ))
wgname = smspec_node_get_wgname( smspec_node );
ecl_kw_iset_string_ptr( wgnames_kw , i , wgname);
}
@@ -486,9 +501,15 @@ void ecl_smspec_fwrite( const ecl_smspec_type * smspec , const char * ecl_case ,
free( filename );
}
ecl_smspec_type * ecl_smspec_alloc_writer( const char * key_join_string , time_t sim_start , bool time_in_days , int nx , int ny , int nz) {
ecl_smspec_type * ecl_smspec_alloc_writer( const char * key_join_string , const char * restart_case, time_t sim_start , bool time_in_days , int nx , int ny , int nz) {
ecl_smspec_type * ecl_smspec = ecl_smspec_alloc_empty( true , key_join_string );
if (restart_case != NULL) {
if (strlen(restart_case) <= (SUMMARY_RESTART_SIZE * ECL_STRING8_LENGTH))
ecl_smspec->restart_case = util_alloc_string_copy( restart_case );
else
return NULL;
}
ecl_smspec->grid_dims[0] = nx;
ecl_smspec->grid_dims[1] = ny;
ecl_smspec->grid_dims[2] = nz;
@@ -989,7 +1010,7 @@ static void ecl_smspec_load_restart( ecl_smspec_type * ecl_smspec , const ecl_fi
char * restart_base;
int i;
tmp_base[0] = '\0';
for (i=0; i < ecl_kw_get_size( restart_kw ); i++)
for (i=0; i < ecl_kw_get_size( restart_kw ); i++)
strcat( tmp_base , ecl_kw_iget_ptr( restart_kw , i ));
restart_base = util_alloc_strip_copy( tmp_base );
@@ -1020,13 +1041,13 @@ void ecl_smspec_index_node( ecl_smspec_type * ecl_smspec , smspec_node_type * sm
well or group name can be left at NULL. In that case the node is
not installed in the different indexes.
*/
// var_type == ECL_SMSPEC_INVALID_VAR??
if (smspec_node_get_gen_key1( smspec_node ) != NULL) {
if (smspec_node_is_valid( smspec_node )) {
ecl_smspec_install_gen_keys( ecl_smspec , smspec_node );
ecl_smspec_install_special_keys( ecl_smspec , smspec_node );
if (smspec_node_need_nums( smspec_node ))
ecl_smspec->need_nums = true;
}
if (smspec_node_need_nums( smspec_node ))
ecl_smspec->need_nums = true;
}
@@ -1073,10 +1094,8 @@ void ecl_smspec_add_node( ecl_smspec_type * ecl_smspec , smspec_node_type * smsp
void ecl_smspec_init_var( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node , const char * keyword , const char * wgname , int num, const char * unit ) {
if (smspec_node_init( smspec_node , ecl_smspec_identify_var_type( keyword ) , wgname , keyword , unit , ecl_smspec->key_join_string , ecl_smspec->grid_dims , num ))
ecl_smspec_index_node( ecl_smspec , smspec_node );
else
util_abort("%s: initializing node failed \n",__func__);
smspec_node_init( smspec_node , ecl_smspec_identify_var_type( keyword ) , wgname , keyword , unit , ecl_smspec->key_join_string , ecl_smspec->grid_dims , num );
ecl_smspec_index_node( ecl_smspec , smspec_node );
}
@@ -1177,10 +1196,7 @@ static bool ecl_smspec_fread_header(ecl_smspec_type * ecl_smspec, const char * h
smspec_node = smspec_node_alloc( var_type , well , kw , unit , ecl_smspec->key_join_string , ecl_smspec->grid_dims , num , params_index , default_value);
if (smspec_node != NULL) {
/** OK - we know this is valid shit. */
ecl_smspec_add_node( ecl_smspec , smspec_node );
}
ecl_smspec_add_node( ecl_smspec , smspec_node );
free( kw );
free( well );
@@ -1861,3 +1877,14 @@ void ecl_smspec_update_wgname( ecl_smspec_type * smspec , smspec_node_type * nod
char * ecl_smspec_alloc_well_key( const ecl_smspec_type * smspec , const char * keyword , const char * wgname) {
return smspec_alloc_well_key( smspec->key_join_string , keyword , wgname );
}
void ecl_smspec_sort( ecl_smspec_type * smspec ) {
vector_sort( smspec->smspec_nodes , smspec_node_cmp__);
for (int i=0; i < vector_get_size( smspec->smspec_nodes ); i++) {
smspec_node_type * node = vector_iget( smspec->smspec_nodes , i );
smspec_node_set_params_index( node , i );
}
}

View File

@@ -303,18 +303,21 @@ ecl_sum_tstep_type * ecl_sum_add_tstep( ecl_sum_type * ecl_sum , int report_step
}
ecl_sum_type * ecl_sum_alloc_writer( const char * ecl_case , bool fmt_output , bool unified , const char * key_join_string , time_t sim_start , bool time_in_days , int nx , int ny , int nz) {
ecl_sum_type * ecl_sum_alloc_restart_writer( const char * ecl_case , const char * restart_case , bool fmt_output , bool unified , const char * key_join_string , time_t sim_start , bool time_in_days , int nx , int ny , int nz) {
ecl_sum_type * ecl_sum = ecl_sum_alloc__( ecl_case , key_join_string );
ecl_sum_set_unified( ecl_sum , unified );
ecl_sum_set_fmt_case( ecl_sum , fmt_output );
ecl_sum->smspec = ecl_smspec_alloc_writer( key_join_string , sim_start , time_in_days , nx , ny , nz );
ecl_sum->smspec = ecl_smspec_alloc_writer( key_join_string , restart_case, sim_start , time_in_days , nx , ny , nz );
ecl_sum->data = ecl_sum_data_alloc_writer( ecl_sum->smspec );
return ecl_sum;
}
ecl_sum_type * ecl_sum_alloc_writer( const char * ecl_case , bool fmt_output , bool unified , const char * key_join_string , time_t sim_start , bool time_in_days , int nx , int ny , int nz) {
return ecl_sum_alloc_restart_writer(ecl_case, NULL, fmt_output, unified, key_join_string, sim_start, time_in_days, nx, ny, nz);
}
void ecl_sum_fwrite( const ecl_sum_type * ecl_sum ) {
ecl_sum_fwrite_smspec( ecl_sum );

View File

@@ -475,7 +475,7 @@ bool fortio_data_fskip(fortio_type* fortio, const int element_size, const int el
void fortio_data_fseek(fortio_type* fortio, offset_type data_offset, size_t data_element, const int element_size, const int element_count, const int block_size) {
if(data_element < 0 || data_element >= element_count) {
if(data_element >= element_count) {
util_abort("%s: Element index is out of range: 0 <= %d < %d \n", __func__, data_element, element_count);
}
{
@@ -681,7 +681,7 @@ static fortio_status_type fortio_check_record( FILE * stream , bool endian_flip
if (tail == header)
/* All OK */
status = FORTIO_OK;
else if ( tail != header )
else
/* The numerical value of the tail did not agree with the header. */
status = FORTIO_HEADER_MISMATCH;
} else
@@ -839,7 +839,7 @@ bool fortio_read_at_eof( fortio_type * fortio ) {
void fortio_fwrite_error(fortio_type * fortio) {
if (fortio->writable)
unlink( fortio->filename );
util_unlink( fortio->filename );
}

View File

@@ -452,7 +452,7 @@ static bool layer_find_edge( const layer_type * layer , int *i , int *j , int va
bool layer_trace_block_edge( const layer_type * layer , int start_i , int start_j , int value , struct_vector_type * corner_list , int_vector_type * cell_list) {
int g = layer_get_global_cell_index( layer , start_i , start_j);
cell_type * cell = &layer->data[g];
if ((cell->cell_value == value)) {
if (cell->cell_value == value) {
int i = start_i;
int j = start_j;

View File

@@ -70,35 +70,13 @@ struct smspec_node_struct {
bool historical; /* Does the name end with 'H'? */
int params_index; /* The index of this variable (applies to all the vectors - in particular the PARAMS vectors of the summary files *.Snnnn / *.UNSMRY ). */
float default_value; /* Default value for this variable. */
bool valid;
};
static bool string_equal(const char * s1 , const char * s2)
{
if ((s1 == NULL) && (s2 == NULL))
return true;
else
return util_string_equal( s1 , s2 );
}
bool smspec_node_equal( const smspec_node_type * node1, const smspec_node_type * node2) {
if ((node1->params_index == node2->params_index) &&
(node1->num == node2->num) &&
(node1->var_type == node2->var_type) &&
(string_equal( node1->keyword, node2->keyword)) &&
(string_equal( node1->wgname, node2->wgname)) &&
(string_equal( node1->unit, node2->unit)) &&
(string_equal( node1->lgr_name, node2->lgr_name)))
{
if (node1->lgr_ijk)
return ((node1->lgr_ijk[0] == node2->lgr_ijk[0]) &&
(node1->lgr_ijk[1] == node2->lgr_ijk[1]) &&
(node1->lgr_ijk[2] == node2->lgr_ijk[2]));
return true;
}
return false;
return smspec_node_cmp( node1 , node2 ) == 0;
}
@@ -128,6 +106,7 @@ bool smspec_node_equal( const smspec_node_type * node1, const smspec_node_type
#define ECL_SUM_KEYFMT_LOCAL_WELL "%s%s%s%s%s"
UTIL_SAFE_CAST_FUNCTION( smspec_node , SMSPEC_TYPE_ID )
static UTIL_SAFE_CAST_FUNCTION_CONST( smspec_node , SMSPEC_TYPE_ID )
char * smspec_alloc_block_num_key( const char * join_string , const char * keyword , int num) {
@@ -295,6 +274,7 @@ static void smspec_node_set_invalid_flags( smspec_node_type * smspec_node) {
smspec_node->rate_variable = false;
smspec_node->total_variable = false;
smspec_node->historical = false;
smspec_node->valid = false;
}
static char LAST_CHAR(const char * s) {
@@ -390,7 +370,6 @@ smspec_node_type * smspec_node_alloc_new(int params_index, float default_value)
smspec_node_set_default( node , default_value );
node->wgname = NULL;
node->num = SMSPEC_NUMS_INVALID;
node->ijk = NULL;
node->gen_key1 = NULL;
@@ -433,6 +412,21 @@ static void smspec_node_set_lgr_ijk( smspec_node_type * index , int lgr_i , int
}
static void smspec_node_init_num( smspec_node_type * node , ecl_smspec_var_type var_type) {
switch( node->var_type ) {
case(ECL_SMSPEC_WELL_VAR):
node->num = SMSPEC_NUMS_WELL;
break;
case(ECL_SMSPEC_GROUP_VAR):
node->num = SMSPEC_NUMS_GROUP;
break;
case(ECL_SMSPEC_FIELD_VAR):
node->num = SMSPEC_NUMS_FIELD;
break;
default:
node->num = SMSPEC_NUMS_INVALID;
}
}
static void smspec_node_set_num( smspec_node_type * index , const int grid_dims[3] , int num) {
if (num == SMSPEC_NUMS_INVALID)
util_abort("%s: explicitly trying to set nums == SMSPEC_NUMS_INVALID - seems like a bug?!\n",__func__);
@@ -550,6 +544,7 @@ static void smspec_node_set_gen_keys( smspec_node_type * smspec_node , const cha
default:
util_abort("%s: internal error - should not be here? \n" , __func__);
}
smspec_node->valid = true;
}
@@ -567,20 +562,23 @@ static void smspec_node_common_init( smspec_node_type * node , ecl_smspec_var_ty
smspec_node_set_keyword( node , keyword);
node->var_type = var_type;
smspec_node_set_flags( node );
smspec_node_init_num( node , var_type );
} else
util_abort("%s: trying to re-init smspec node with keyword:%s - invalid \n",__func__ , keyword );
}
bool smspec_node_init( smspec_node_type * smspec_node,
ecl_smspec_var_type var_type ,
const char * wgname ,
const char * keyword ,
const char * unit ,
const char * key_join_string ,
const int grid_dims[3] ,
int num) {
/*
This *should* become static.
*/
void smspec_node_init( smspec_node_type * smspec_node,
ecl_smspec_var_type var_type ,
const char * wgname ,
const char * keyword ,
const char * unit ,
const char * key_join_string ,
const int grid_dims[3] ,
int num) {
bool initOK = true;
bool wgnameOK = true;
@@ -591,31 +589,25 @@ bool smspec_node_init( smspec_node_type * smspec_node,
switch (var_type) {
case(ECL_SMSPEC_COMPLETION_VAR):
/* Completion variable : WGNAME & NUM */
if (wgnameOK) {
smspec_node_set_num( smspec_node , grid_dims , num );
smspec_node_set_wgname( smspec_node , wgname );
} else
smspec_node_set_num( smspec_node , grid_dims , num );
smspec_node_set_wgname( smspec_node , wgname );
if (!wgnameOK || num < 0)
initOK = false;
break;
case(ECL_SMSPEC_GROUP_VAR):
/* Group variable : WGNAME */
if (wgnameOK)
smspec_node_set_wgname( smspec_node , wgname );
else
initOK = false;
smspec_node_set_wgname( smspec_node , wgname );
initOK = wgnameOK;
break;
case(ECL_SMSPEC_WELL_VAR):
/* Well variable : WGNAME */
if (wgnameOK)
smspec_node_set_wgname( smspec_node , wgname );
else
initOK = false;
smspec_node_set_wgname( smspec_node , wgname );
initOK = wgnameOK;
break;
case(ECL_SMSPEC_SEGMENT_VAR):
if (wgnameOK && num >= 0) {
smspec_node_set_wgname( smspec_node , wgname );
smspec_node_set_num( smspec_node , grid_dims , num );
} else
smspec_node_set_wgname( smspec_node , wgname );
smspec_node_set_num( smspec_node , grid_dims , num );
if (!wgnameOK || num < 0)
initOK = false;
break;
case(ECL_SMSPEC_FIELD_VAR):
@@ -662,7 +654,6 @@ bool smspec_node_init( smspec_node_type * smspec_node,
if (initOK)
smspec_node_set_gen_keys( smspec_node , key_join_string );
return initOK;
}
/**
@@ -719,25 +710,21 @@ smspec_node_type * smspec_node_alloc( ecl_smspec_var_type var_type ,
*/
smspec_node_type * smspec_node = smspec_node_alloc_new( param_index , default_value );
if (smspec_node_init( smspec_node , var_type , wgname , keyword , unit , key_join_string , grid_dims, num))
return smspec_node;
else {
smspec_node_free( smspec_node );
return NULL;
}
smspec_node_init( smspec_node , var_type , wgname , keyword , unit , key_join_string , grid_dims, num);
return smspec_node;
}
bool smspec_node_init_lgr( smspec_node_type * smspec_node ,
ecl_smspec_var_type var_type ,
const char * wgname ,
const char * keyword ,
const char * unit ,
const char * lgr ,
const char * key_join_string ,
int lgr_i, int lgr_j , int lgr_k
) {
static void smspec_node_init_lgr( smspec_node_type * smspec_node ,
ecl_smspec_var_type var_type ,
const char * wgname ,
const char * keyword ,
const char * unit ,
const char * lgr ,
const char * key_join_string ,
int lgr_i, int lgr_j , int lgr_k
) {
bool initOK = true;
bool wgnameOK = true;
if ((wgname != NULL) && (IS_DUMMY_WELL(wgname)))
@@ -746,30 +733,26 @@ bool smspec_node_init_lgr( smspec_node_type * smspec_node ,
smspec_node_common_init( smspec_node , var_type , keyword , unit );
switch (var_type) {
case(ECL_SMSPEC_LOCAL_WELL_VAR):
if (wgnameOK) {
smspec_node_set_wgname( smspec_node , wgname );
smspec_node_set_lgr_name( smspec_node , lgr );
} else
initOK = false;
smspec_node_set_wgname( smspec_node , wgname );
smspec_node_set_lgr_name( smspec_node , lgr );
initOK = wgnameOK;
break;
case(ECL_SMSPEC_LOCAL_BLOCK_VAR):
smspec_node_set_lgr_name( smspec_node , lgr );
smspec_node_set_lgr_ijk( smspec_node , lgr_i, lgr_j , lgr_k );
break;
case(ECL_SMSPEC_LOCAL_COMPLETION_VAR):
if (wgnameOK) {
smspec_node_set_lgr_name( smspec_node , lgr );
smspec_node_set_wgname( smspec_node , wgname );
smspec_node_set_lgr_ijk( smspec_node , lgr_i, lgr_j , lgr_k );
} else
initOK = false;
smspec_node_set_lgr_name( smspec_node , lgr );
smspec_node_set_wgname( smspec_node , wgname );
smspec_node_set_lgr_ijk( smspec_node , lgr_i, lgr_j , lgr_k );
initOK = wgnameOK;
break;
default:
util_abort("%s: internal error: in LGR function with non-LGR keyword:%s \n",__func__ , keyword);
}
if (initOK)
smspec_node_set_gen_keys( smspec_node , key_join_string );
return initOK;
}
@@ -784,12 +767,8 @@ smspec_node_type * smspec_node_alloc_lgr( ecl_smspec_var_type var_type ,
int param_index , float default_value) {
smspec_node_type * smspec_node = smspec_node_alloc_new( param_index , default_value );
if (smspec_node_init_lgr( smspec_node , var_type , wgname , keyword , unit , lgr , key_join_string , lgr_i, lgr_j , lgr_k))
return smspec_node;
else {
smspec_node_free( smspec_node );
return NULL;
}
smspec_node_init_lgr( smspec_node , var_type , wgname , keyword , unit , lgr , key_join_string , lgr_i, lgr_j , lgr_k);
return smspec_node;
}
smspec_node_type* smspec_node_alloc_copy( const smspec_node_type* node ) {
@@ -820,6 +799,7 @@ smspec_node_type* smspec_node_alloc_copy( const smspec_node_type* node ) {
memcpy( copy->lgr_ijk, node->lgr_ijk, 3 * sizeof( * node->lgr_ijk ) );
}
copy->valid = node->valid;
copy->rate_variable = node->rate_variable;
copy->total_variable = node->total_variable;
copy->historical = node->historical;
@@ -901,6 +881,11 @@ bool smspec_node_is_historical( const smspec_node_type * smspec_node ){
}
bool smspec_node_is_valid( const smspec_node_type * smspec_node ){
return smspec_node->valid;
}
const char * smspec_node_get_unit( const smspec_node_type * smspec_node) {
return smspec_node->unit;
}
@@ -980,3 +965,220 @@ void smspec_node_fprintf( const smspec_node_type * smspec_node , FILE * stream)
fprintf(stream, "WGNAME : %s \n",smspec_node->wgname);
fprintf(stream, "UNIT : %s \n",smspec_node->unit);
}
static bool smspec_node_equal_MISC( const smspec_node_type * node1, const smspec_node_type * node2) {
return util_string_equal( node1->keyword , node2->keyword);
}
/*
MISC variables are generally sorted to the end of the list,
but some special case variables come at the very beginning.
*/
static int smspec_node_cmp_MISC( const smspec_node_type * node1, const smspec_node_type * node2) {
static const char* early_vars[] = {"TIME",
"DAYS",
"DAY",
"MONTH",
"YEAR",
"YEARS"};
if (smspec_node_equal_MISC( node1, node2) )
return 0;
bool node1_early = false;
bool node2_early = false;
for (int i=0; i < 6; i++) {
if (util_string_equal( node1->keyword, early_vars[i] ))
node1_early = true;
if (util_string_equal( node2->keyword, early_vars[i] ))
node2_early = true;
}
if (node1_early && !node2_early)
return -1;
if (!node1_early && node2_early)
return 1;
return strcmp( node1->keyword, node2->keyword);
}
static int int_cmp(int v1, int v2) {
if (v1 < v2)
return -1;
if (v1 > v2)
return 1;
return 0;
}
static int smspec_node_cmp_LGRIJK( const smspec_node_type * node1, const smspec_node_type * node2) {
int i_cmp = int_cmp( node1->lgr_ijk[0] , node2->lgr_ijk[0]);
if (i_cmp != 0)
return i_cmp;
int j_cmp = int_cmp( node1->lgr_ijk[1] , node2->lgr_ijk[1]);
if (j_cmp != 0)
return j_cmp;
return int_cmp( node1->lgr_ijk[2] , node2->lgr_ijk[2]);
}
static int smspec_node_cmp_KEYWORD_LGR_LGRIJK( const smspec_node_type * node1, const smspec_node_type * node2) {
int keyword_cmp = strcmp( node1->keyword , node2->keyword);
if (keyword_cmp != 0)
return keyword_cmp;
int lgr_cmp = strcmp( node1->lgr_name , node2->lgr_name);
if (lgr_cmp != 0)
return lgr_cmp;
return smspec_node_cmp_LGRIJK( node1, node2);
}
static int smspec_node_cmp_KEYWORD_WGNAME_NUM( const smspec_node_type * node1, const smspec_node_type * node2) {
int keyword_cmp = strcmp( node1->keyword , node2->keyword);
if (keyword_cmp != 0)
return keyword_cmp;
int wgname_cmp = strcmp( node1->wgname , node2->wgname);
if (wgname_cmp != 0)
return wgname_cmp;
return int_cmp( node1->num , node2->num);
}
static int smspec_node_cmp_KEYWORD_WGNAME_LGR( const smspec_node_type * node1, const smspec_node_type * node2) {
int keyword_cmp = strcmp( node1->keyword , node2->keyword);
if (keyword_cmp != 0)
return keyword_cmp;
int wgname_cmp = strcmp( node1->wgname , node2->wgname);
if (wgname_cmp != 0)
return wgname_cmp;
return strcmp( node1->lgr_name , node2->lgr_name);
}
static int smspec_node_cmp_KEYWORD_WGNAME_LGR_LGRIJK( const smspec_node_type * node1, const smspec_node_type * node2) {
int keyword_cmp = strcmp( node1->keyword , node2->keyword);
if (keyword_cmp != 0)
return keyword_cmp;
int wgname_cmp = strcmp( node1->wgname , node2->wgname);
if (wgname_cmp != 0)
return wgname_cmp;
int lgr_cmp = strcmp( node1->lgr_name , node2->lgr_name);
if (lgr_cmp != 0)
return lgr_cmp;
return smspec_node_cmp_LGRIJK( node1, node2);
}
static int smspec_node_cmp_KEYWORD_WGNAME( const smspec_node_type * node1, const smspec_node_type * node2) {
int keyword_cmp = strcmp( node1->keyword , node2->keyword);
if (keyword_cmp != 0)
return keyword_cmp;
if (IS_DUMMY_WELL( node1->wgname )) {
if (IS_DUMMY_WELL( node2->wgname ))
return 0;
else
return 1;
}
if (IS_DUMMY_WELL( node2->wgname ))
return -1;
return strcmp( node1->wgname , node2->wgname);
}
static int smspec_node_cmp_KEYWORD_NUM( const smspec_node_type * node1, const smspec_node_type * node2) {
int keyword_cmp = strcmp( node1->keyword , node2->keyword);
if (keyword_cmp != 0)
return keyword_cmp;
return int_cmp( node1->num , node2->num);
}
static int smspec_node_cmp_KEYWORD( const smspec_node_type * node1, const smspec_node_type * node2) {
return strcmp( node1->keyword , node2->keyword );
}
static int smspec_node_cmp_key1( const smspec_node_type * node1, const smspec_node_type * node2) {
return util_strcmp_int( node1->gen_key1 , node2->gen_key1 );
}
int smspec_node_cmp( const smspec_node_type * node1, const smspec_node_type * node2) {
/* 1: Start with special casing for the MISC variables. */
if ((node1->var_type == ECL_SMSPEC_MISC_VAR) || (node2->var_type == ECL_SMSPEC_MISC_VAR))
return smspec_node_cmp_MISC( node1 , node2 );
/* 2: Sort according to variable type */
if (node1->var_type < node2->var_type)
return -1;
if (node1->var_type > node2->var_type)
return 1;
/* 3: Internal sort of variables of the same type. */
switch (node1->var_type) {
case( ECL_SMSPEC_FIELD_VAR):
return smspec_node_cmp_KEYWORD( node1, node2);
case( ECL_SMSPEC_WELL_VAR):
case( ECL_SMSPEC_GROUP_VAR):
return smspec_node_cmp_KEYWORD_WGNAME( node1, node2);
case( ECL_SMSPEC_BLOCK_VAR):
case( ECL_SMSPEC_REGION_VAR):
case( ECL_SMSPEC_REGION_2_REGION_VAR):
case( ECL_SMSPEC_AQUIFER_VAR):
return smspec_node_cmp_KEYWORD_NUM( node1, node2);
case( ECL_SMSPEC_COMPLETION_VAR):
case( ECL_SMSPEC_SEGMENT_VAR):
return smspec_node_cmp_KEYWORD_WGNAME_NUM( node1, node2);
case (ECL_SMSPEC_NETWORK_VAR):
return smspec_node_cmp_key1( node1, node2);
case( ECL_SMSPEC_LOCAL_BLOCK_VAR):
return smspec_node_cmp_KEYWORD_LGR_LGRIJK( node1, node2);
case( ECL_SMSPEC_LOCAL_WELL_VAR):
return smspec_node_cmp_KEYWORD_WGNAME_LGR( node1, node2);
case( ECL_SMSPEC_LOCAL_COMPLETION_VAR):
return smspec_node_cmp_KEYWORD_WGNAME_LGR_LGRIJK( node1, node2);
default:
/* Should not really end up here. */
return smspec_node_cmp_key1( node1, node2);
}
}
int smspec_node_cmp__( const void * node1, const void * node2) {
return smspec_node_cmp( smspec_node_safe_cast_const( node1 ),
smspec_node_safe_cast_const( node2 ));
}

View File

@@ -0,0 +1,117 @@
/*
Copyright (C) 2017 Statoil ASA, Norway.
The file 'ecl_file_view.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.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <ert/util/test_util.h>
#include <ert/util/util.h>
#include <ert/util/test_work_area.h>
#include <ert/ecl/ecl_util.h>
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_file_view.h>
#include <ert/ecl/ecl_file_kw.h>
void test_file_kw_equal() {
ecl_file_kw_type * kw1 = ecl_file_kw_alloc0( "PRESSURE" , ECL_FLOAT, 1000 , 66);
ecl_file_kw_type * kw2 = ecl_file_kw_alloc0( "PRESSURE" , ECL_FLOAT, 1000 , 66);
ecl_file_kw_type * kw3 = ecl_file_kw_alloc0( "SWAT" , ECL_FLOAT, 1000 , 66);
ecl_file_kw_type * kw4 = ecl_file_kw_alloc0( "PRESSURE" , ECL_DOUBLE, 1000 , 66);
ecl_file_kw_type * kw5 = ecl_file_kw_alloc0( "PRESSURE" , ECL_FLOAT, 10 , 66);
ecl_file_kw_type * kw6 = ecl_file_kw_alloc0( "PRESSURE" , ECL_FLOAT, 1000 , 67);
test_assert_true( ecl_file_kw_equal( kw1 , kw1 ));
test_assert_true( ecl_file_kw_equal( kw1 , kw2 ));
test_assert_false( ecl_file_kw_equal( kw1 , kw3 ));
test_assert_false( ecl_file_kw_equal( kw1 , kw4 ));
test_assert_false( ecl_file_kw_equal( kw1 , kw5 ));
test_assert_false( ecl_file_kw_equal( kw1 , kw6 ));
ecl_file_kw_free( kw6 );
ecl_file_kw_free( kw5 );
ecl_file_kw_free( kw4 );
ecl_file_kw_free( kw3 );
ecl_file_kw_free( kw2 );
ecl_file_kw_free( kw1 );
}
void test_create_file_kw() {
ecl_file_kw_type * file_kw0 = ecl_file_kw_alloc0( "PRESSURE" , ECL_FLOAT, 1000 , 66);
ecl_file_kw_type * file_kw1 = ecl_file_kw_alloc0( "TEST1_KW" , ECL_FLOAT, 2000 , 1066);
ecl_file_kw_type * file_kw2 = ecl_file_kw_alloc0( "TEST2_KW" , ECL_FLOAT, 3000 , 2066);
test_assert_string_equal( ecl_file_kw_get_header( file_kw0 ) , "PRESSURE" );
test_assert_int_equal( ecl_file_kw_get_size( file_kw0 ) , 1000 );
test_assert_true( ecl_type_is_equal( ecl_file_kw_get_data_type( file_kw0 ) , ECL_FLOAT ));
{
test_work_area_type * work_area = test_work_area_alloc("file_kw");
{
FILE * ostream = util_fopen("file_kw" , "w");
ecl_file_kw_fwrite( file_kw0 , ostream );
fclose( ostream );
}
{
FILE * istream = util_fopen("file_kw" , "r");
ecl_file_kw_type * disk_kw = ecl_file_kw_fread_alloc( istream );
test_assert_true( ecl_file_kw_equal( file_kw0 , disk_kw ));
/* Beyond the end of stream - return NULL */
test_assert_NULL( ecl_file_kw_fread_alloc( istream ));
ecl_file_kw_free( disk_kw );
fclose( istream );
}
{
FILE * ostream = util_fopen("file_kw" , "w");
ecl_file_kw_fwrite( file_kw0 , ostream );
ecl_file_kw_fwrite( file_kw1 , ostream );
ecl_file_kw_fwrite( file_kw2 , ostream );
fclose( ostream );
}
{
FILE * istream = util_fopen("file_kw" , "r");
ecl_file_kw_type ** disk_kw = ecl_file_kw_fread_alloc_multiple( istream , 3);
test_assert_true( ecl_file_kw_equal( file_kw0 , disk_kw[0] ));
test_assert_true( ecl_file_kw_equal( file_kw1 , disk_kw[1] ));
test_assert_true( ecl_file_kw_equal( file_kw2 , disk_kw[2] ));
for (int i=0; i < 3; i++)
ecl_file_kw_free( disk_kw[i] );
free( disk_kw );
fclose( istream );
}
{
FILE * istream = util_fopen("file_kw" , "r");
test_assert_NULL( ecl_file_kw_fread_alloc_multiple( istream , 10));
fclose( istream );
}
test_work_area_free( work_area );
}
ecl_file_kw_free( file_kw0 );
ecl_file_kw_free( file_kw1 );
ecl_file_kw_free( file_kw2 );
}
int main( int argc , char ** argv) {
util_install_signals();
test_file_kw_equal( );
test_create_file_kw( );
}

View File

@@ -116,7 +116,7 @@ void test_contains( const ecl_grid_type * grid ) {
for (int k=0; k < nz; k++) {
for (int j=0; j < ny; j++) {
for (int i=0; i < nx; i++) {
if (!ecl_grid_get_cell_twist3( grid , i,j,k) == 0) {
if (ecl_grid_get_cell_twist3( grid , i,j,k) != 0) {
double x,y,z;
if (get_test_point3( grid , i,j,k , &x,&y,&z)) {
assert_contains( grid , i , j , k , x , y , z);

View File

@@ -71,7 +71,7 @@ vector_type * load_expected( const ecl_grid_type * grid, const char * filename )
}
int test_well_point(const ecl_grid_type * grid, const point_type * expected) {
void test_well_point(const ecl_grid_type * grid, const point_type * expected) {
int g = ecl_grid_get_global_index_from_xyz(grid , expected->x, expected->y , expected->z , 0 );
if (g != ecl_grid_get_global_index3(grid, expected->i,expected->j, expected->k)) {
int i,j,k;

View File

@@ -23,6 +23,20 @@
#include <ert/ecl/ecl_smspec.h>
void test_sort( ecl_smspec_type * smspec )
{
int num_nodes = ecl_smspec_num_nodes( smspec );
ecl_smspec_sort( smspec );
test_assert_int_equal( num_nodes, ecl_smspec_num_nodes( smspec ));
for (int i=1; i < ecl_smspec_num_nodes( smspec ); i++) {
const smspec_node_type * node1 = ecl_smspec_iget_node( smspec, i - 1 );
const smspec_node_type * node2 = ecl_smspec_iget_node( smspec, i );
test_assert_true( smspec_node_cmp( node1 , node2 ) <= 0 );
test_assert_int_equal( smspec_node_get_params_index( node1 ) , i - 1 );
}
}
int main(int argc, char ** argv) {
@@ -37,6 +51,8 @@ int main(int argc, char ** argv) {
test_assert_false( ecl_smspec_equal( smspec1 , smspec2 ));
test_assert_false( ecl_smspec_equal( smspec2 , smspec1 ));
test_sort( smspec1 );
test_sort( smspec2 );
ecl_smspec_free( smspec1 );
ecl_smspec_free( smspec2 );
}

View File

@@ -0,0 +1,129 @@
/*
Copyright (C) 2017 Statoil ASA, Norway.
This file 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.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/util.h>
#include <ert/util/test_util.h>
#include <ert/ecl/smspec_node.h>
void test_cmp_types() {
const int dims[3] = {10,10,10};
smspec_node_type * field_node = smspec_node_alloc( ECL_SMSPEC_FIELD_VAR , NULL , "FOPT" , "UNIT" , ":" , dims , 0 , 0 , 0 );
smspec_node_type * region_node = smspec_node_alloc( ECL_SMSPEC_REGION_VAR , NULL , "RPR" , "UNIT" , ":" , dims , 10 , 0 , 0 );
smspec_node_type * group_node = smspec_node_alloc( ECL_SMSPEC_GROUP_VAR , "G1" , "GOPR" , "UNIT" , ":" , dims , 10 , 0 , 0 );
smspec_node_type * well_node = smspec_node_alloc( ECL_SMSPEC_WELL_VAR , "W1" , "WOPR" , "UNIT" , ":" , dims , 10 , 0 , 0 );
smspec_node_type * block_node = smspec_node_alloc( ECL_SMSPEC_BLOCK_VAR , NULL , "BPR" , "UNIT" , ":" , dims , 10 , 0 , 0 );
smspec_node_type * aquifer_node = smspec_node_alloc( ECL_SMSPEC_AQUIFER_VAR , NULL , "AAQP" , "UNIT" , ":" , dims , 10 , 0 , 0 );
smspec_node_type * segment_node = smspec_node_alloc( ECL_SMSPEC_SEGMENT_VAR , "W1" , "SGOR" , "UNIT" , ":" , dims , 10 , 0 , 0 );
smspec_node_type * misc_node1 = smspec_node_alloc( ECL_SMSPEC_MISC_VAR , NULL , "TIME" , "UNIT" , ":", dims, 10 , 0, 0);
smspec_node_type * misc_node2 = smspec_node_alloc( ECL_SMSPEC_MISC_VAR , NULL , "TCPU" , "UNIT" , ":", dims, 10 , 0, 0);
test_assert_int_equal( smspec_node_cmp( field_node , field_node ), 0);
test_assert_int_equal( smspec_node_cmp( region_node , region_node ), 0);
test_assert_int_equal( smspec_node_cmp( well_node , well_node ), 0);
test_assert_int_equal( smspec_node_cmp( group_node , group_node ), 0);
test_assert_int_equal( smspec_node_cmp( block_node , block_node ), 0);
test_assert_true( smspec_node_cmp( misc_node1 , field_node ) < 0 );
test_assert_true( smspec_node_cmp( field_node , region_node ) < 0 );
test_assert_true( smspec_node_cmp( region_node , group_node ) < 0 );
test_assert_true( smspec_node_cmp( group_node , well_node ) < 0 );
test_assert_true( smspec_node_cmp( well_node , segment_node ) < 0 );
test_assert_true( smspec_node_cmp( segment_node , block_node ) < 0 );
test_assert_true( smspec_node_cmp( block_node , aquifer_node) < 0 );
test_assert_true( smspec_node_cmp( aquifer_node , misc_node2 ) < 0 );
test_assert_true( smspec_node_cmp( field_node, misc_node1) > 0 );
test_assert_true( smspec_node_cmp( misc_node2, aquifer_node) > 0 );
test_assert_true( smspec_node_cmp( misc_node1, misc_node2) < 0 );
test_assert_true( smspec_node_cmp( misc_node2, misc_node1) > 0 );
smspec_node_free( segment_node );
smspec_node_free( aquifer_node );
smspec_node_free( block_node );
smspec_node_free( group_node );
smspec_node_free( well_node );
smspec_node_free( region_node );
smspec_node_free( field_node );
smspec_node_free( misc_node1 );
smspec_node_free( misc_node2 );
}
void test_cmp_well() {
const int dims[3] = {10,10,10};
smspec_node_type * well_node1_1 = smspec_node_alloc( ECL_SMSPEC_WELL_VAR , "W1" , "WOPR" , "UNIT" , ":" , dims , 10 , 0 , 0 );
smspec_node_type * well_node1_2 = smspec_node_alloc( ECL_SMSPEC_WELL_VAR , "W2" , "WOPR" , "UNIT" , ":" , dims , 10 , 0 , 0 );
smspec_node_type * well_node2_1 = smspec_node_alloc( ECL_SMSPEC_WELL_VAR , "W1" , "WWCT" , "UNIT" , ":" , dims , 10 , 0 , 0 );
smspec_node_type * well_node2_2 = smspec_node_alloc( ECL_SMSPEC_WELL_VAR , "W2" , "WWWT" , "UNIT" , ":" , dims , 10 , 0 , 0 );
smspec_node_type * well_node_dummy = smspec_node_alloc( ECL_SMSPEC_WELL_VAR , DUMMY_WELL , "WOPR" , "UNIT" , ":" , dims , 10 , 0 , 0 );
test_assert_int_equal( smspec_node_cmp( well_node1_1 , well_node1_1 ), 0);
test_assert_int_equal( smspec_node_cmp( well_node2_2 , well_node2_2 ), 0);
test_assert_true( smspec_node_cmp( well_node1_1, well_node1_2) < 0 );
test_assert_true( smspec_node_cmp( well_node1_1, well_node2_1) < 0 );
test_assert_true( smspec_node_cmp( well_node1_1, well_node2_2) < 0 );
test_assert_true( smspec_node_cmp( well_node1_2, well_node1_1) > 0 );
test_assert_true( smspec_node_cmp( well_node1_2, well_node2_1) < 0 );
test_assert_true( smspec_node_cmp( well_node1_1, well_node_dummy) < 0 );
test_assert_false( smspec_node_is_valid( well_node_dummy ));
test_assert_true( smspec_node_is_valid( well_node1_1 ));
smspec_node_free( well_node1_1 );
smspec_node_free( well_node2_1 );
smspec_node_free( well_node1_2 );
smspec_node_free( well_node2_2 );
smspec_node_free( well_node_dummy );
}
void test_cmp_region() {
const int dims[3] = {10,10,10};
smspec_node_type * region_node1_1 = smspec_node_alloc( ECL_SMSPEC_REGION_VAR , NULL , "ROIP" , "UNIT" , ":" , dims , 10 , 0 , 0 );
smspec_node_type * region_node1_2 = smspec_node_alloc( ECL_SMSPEC_REGION_VAR , NULL , "ROIP" , "UNIT" , ":" , dims , 11 , 0 , 0 );
smspec_node_type * region_node2_1 = smspec_node_alloc( ECL_SMSPEC_REGION_VAR , NULL , "RPR" , "UNIT" , ":" , dims , 10 , 0 , 0 );
smspec_node_type * region_node2_2 = smspec_node_alloc( ECL_SMSPEC_REGION_VAR , NULL , "RPR" , "UNIT" , ":" , dims , 12 , 0 , 0 );
test_assert_true( smspec_node_cmp( region_node1_1, region_node1_2) < 0 );
test_assert_true( smspec_node_cmp( region_node1_1, region_node2_1) < 0 );
test_assert_true( smspec_node_cmp( region_node1_1, region_node2_2) < 0 );
test_assert_true( smspec_node_cmp( region_node1_2, region_node1_1) > 0 );
test_assert_true( smspec_node_cmp( region_node1_2, region_node2_1) < 0 );
smspec_node_free( region_node1_1 );
smspec_node_free( region_node2_1 );
smspec_node_free( region_node1_2 );
smspec_node_free( region_node2_2 );
}
int main(int argc, char ** argv) {
util_install_signals();
test_cmp_types();
test_cmp_well();
test_cmp_region( );
}

View File

@@ -25,9 +25,11 @@
#include <ert/ecl/ecl_sum.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_kw_magic.h>
void write_summary( const char * name , time_t start_time , int nx , int ny , int nz , int num_dates, int num_ministep, double ministep_length) {
double write_summary( const char * name , time_t start_time , int nx , int ny , int nz , int num_dates, int num_ministep, double ministep_length) {
ecl_sum_type * ecl_sum = ecl_sum_alloc_writer( name , false , true , ":" , start_time , true , nx , ny , nz );
double sim_seconds = 0;
@@ -54,6 +56,35 @@ void write_summary( const char * name , time_t start_time , int nx , int ny , in
}
ecl_sum_fwrite( ecl_sum );
ecl_sum_free( ecl_sum );
return sim_seconds;
}
int write_restart_summary(const char * name, const char * restart_name , int start_report_step, double sim_seconds, time_t start_time , int nx , int ny , int nz , int num_dates, int num_ministep, double ministep_length) {
ecl_sum_type * ecl_sum = ecl_sum_alloc_restart_writer( name , restart_name, false , true , ":" , start_time , true , nx , ny , nz );
smspec_node_type * node1 = ecl_sum_add_var( ecl_sum , "FOPT" , NULL , 0 , "Barrels" , 99.0 );
smspec_node_type * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 567 , "BARS" , 0.0 );
smspec_node_type * node3 = ecl_sum_add_var( ecl_sum , "WWCT" , "OP-1" , 0 , "(1)" , 0.0 );
int num_report_steps = start_report_step + num_dates;
for (int report_step = start_report_step; report_step < num_report_steps; report_step++) {
for (int step = 0; step < num_ministep; step++) {
{
ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum , report_step + 1 , sim_seconds );
ecl_sum_tstep_set_from_node( tstep , node1 , sim_seconds);
ecl_sum_tstep_set_from_node( tstep , node2 , 10*sim_seconds );
ecl_sum_tstep_set_from_node( tstep , node3 , 100*sim_seconds );
}
sim_seconds += ministep_length;
}
}
ecl_sum_fwrite( ecl_sum );
ecl_sum_free( ecl_sum );
return sim_seconds;
}
@@ -102,8 +133,85 @@ void test_write_read( ) {
}
void test_ecl_sum_alloc_restart_writer() {
test_work_area_type * work_area = test_work_area_alloc("sum_write_restart");
{
const char * name1 = "CASE1";
const char * name2 = "CASE2";
time_t start_time = util_make_date_utc( 1,1,2010 );
int nx = 10;
int ny = 11;
int nz = 12;
int num_dates = 5;
int num_ministep = 10;
double ministep_length = 36000; // Seconds
int sim_seconds = write_summary( name1 , start_time , nx , ny , nz , num_dates , num_ministep , ministep_length);
sim_seconds = write_restart_summary( name2 , name1 , num_dates, sim_seconds, start_time , nx , ny , nz , num_dates , num_ministep , ministep_length);
ecl_sum_type * case1 = ecl_sum_fread_alloc_case( name1 , ":" );
ecl_sum_type * case2 = ecl_sum_fread_alloc_case( name2 , ":" );
test_assert_true( ecl_sum_is_instance(case2) );
test_assert_true( ecl_sum_has_key( case2 , "FOPT" ));
ecl_file_type * restart_file = ecl_file_open( "CASE2.SMSPEC" , 0 );
ecl_file_view_type * view_file = ecl_file_get_global_view( restart_file );
test_assert_true( ecl_file_view_has_kw(view_file, RESTART_KW));
ecl_kw_type * kw = ecl_file_view_iget_kw(view_file, 0);
test_assert_int_equal(8, ecl_kw_get_size(kw));
test_assert_string_equal( "CASE1 ", ecl_kw_iget_ptr( kw , 0 ) );
test_assert_string_equal( " ", ecl_kw_iget_ptr( kw , 1 ) );
for (int time_index=0; time_index < ecl_sum_get_data_length( case1 ); time_index++)
test_assert_double_equal( ecl_sum_get_general_var( case1 , time_index , "FOPT"), ecl_sum_get_general_var( case2 , time_index , "FOPT"));
ecl_sum_free(case2);
ecl_sum_free(case1);
ecl_file_close(restart_file);
}
test_work_area_free( work_area );
}
void test_long_restart_names() {
char restart_case[65] = { 0 };
for (int n = 0; n < 8; n++) {
char s[9];
sprintf(s, "WWWWGGG%d", n);
strcat(restart_case, s);
}
const char * name = "THE_CASE";
test_work_area_type * work_area = test_work_area_alloc("sum_write_restart_long_name");
{
time_t start_time = util_make_date_utc( 1,1,2010 );
ecl_sum_type * ecl_sum = ecl_sum_alloc_restart_writer( name , restart_case , false , true , ":" , start_time , true , 3, 3, 3);
ecl_sum_fwrite( ecl_sum );
ecl_sum_free(ecl_sum);
ecl_file_type * smspec_file = ecl_file_open( "THE_CASE.SMSPEC" , 0 );
ecl_file_view_type * view_file = ecl_file_get_global_view( smspec_file );
test_assert_true( ecl_file_view_has_kw(view_file, RESTART_KW));
ecl_kw_type * kw = ecl_file_view_iget_kw(view_file, 0);
test_assert_int_equal(8, ecl_kw_get_size(kw));
for (int n = 0; n < 8; n++) {
char s[9]; sprintf(s, "WWWWGGG%d", n);
test_assert_string_equal(s, ecl_kw_iget_char_ptr(kw, n) );
}
test_assert_NULL( ecl_smspec_alloc_writer( ":" , "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ", start_time, true, 3, 3 ,3) );
}
test_work_area_free( work_area );
}
int main( int argc , char ** argv) {
test_write_read();
test_ecl_sum_alloc_restart_writer();
test_long_restart_names();
exit(0);
}

View File

@@ -0,0 +1,109 @@
/*
Copyright (C) 2017 Statoil ASA, Norway.
The file 'test_ecl_file_index.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.
*/
#include <stdio.h>
#include <utime.h>
#include <ert/util/test_util.h>
#include <ert/util/util.h>
#include <ert/util/test_work_area.h>
#include <ert/ecl/ecl_endian_flip.h>
#include <ert/ecl/ecl_file.h>
void test_load_nonexisting_file() {
ecl_file_type * ecl_file = ecl_file_fast_open("base_file", "a_file_that_does_not_exist_2384623", 0);
test_assert_NULL( ecl_file );
}
void test_create_and_load_index_file() {
test_work_area_type * work_area = test_work_area_alloc("ecl_file_index_testing");
{
char * file_name = "initial_data_file";
char * index_file_name = "index_file";
//creating the data file
size_t data_size = 10;
ecl_kw_type * kw1 = ecl_kw_alloc("TEST1_KW", data_size, ECL_INT);
for(int i = 0; i < data_size; ++i)
ecl_kw_iset_int(kw1, i, 537 + i);
fortio_type * fortio = fortio_open_writer(file_name, false, ECL_ENDIAN_FLIP);
ecl_kw_fwrite(kw1, fortio);
data_size = 5;
ecl_kw_type * kw2 = ecl_kw_alloc("TEST2_KW", data_size, ECL_FLOAT);
for(int i = 0; i < data_size; ++i)
ecl_kw_iset_float(kw2, i, 0.15 * i);
ecl_kw_fwrite(kw2, fortio);
fortio_fclose(fortio);
//finished creating data file
//creating ecl_file
ecl_file_type * ecl_file = ecl_file_open( file_name , 0 );
test_assert_true( ecl_file_has_kw( ecl_file , "TEST1_KW" ) );
ecl_file_write_index( ecl_file , index_file_name);
int ecl_file_size = ecl_file_get_size( ecl_file );
ecl_file_close( ecl_file );
//finished using ecl_file
test_assert_false( ecl_file_index_valid(file_name, "nofile"));
test_assert_false( ecl_file_index_valid("nofile", index_file_name));
struct utimbuf tm1 = {1 , 1};
struct utimbuf tm2 = {2 , 2};
utime(file_name, &tm2);
utime(index_file_name, &tm1);
test_assert_false( ecl_file_index_valid(file_name, index_file_name) );
utime(file_name, &tm1);
utime(index_file_name, &tm2);
test_assert_true( ecl_file_index_valid(file_name, index_file_name) );
ecl_file_type * ecl_file_index = ecl_file_fast_open( file_name, index_file_name , 0);
test_assert_true( ecl_file_is_instance(ecl_file_index) );
test_assert_true( ecl_file_get_global_view(ecl_file_index) );
test_assert_int_equal(ecl_file_size, ecl_file_get_size(ecl_file_index) );
test_assert_true( ecl_file_has_kw( ecl_file_index, "TEST1_KW" ) );
test_assert_true( ecl_file_has_kw( ecl_file_index, "TEST2_KW" ) );
ecl_kw_type * kwi1 = ecl_file_iget_kw( ecl_file_index , 0 );
test_assert_true (ecl_kw_equal(kw1, kwi1));
test_assert_double_equal( 537.0, ecl_kw_iget_as_double(kwi1, 0) );
test_assert_double_equal( 546.0, ecl_kw_iget_as_double(kwi1, 9) );
ecl_kw_type * kwi2 = ecl_file_iget_kw( ecl_file_index , 1 );
test_assert_true (ecl_kw_equal(kw2, kwi2));
test_assert_double_equal( 0.15, ecl_kw_iget_as_double(kwi2, 1) );
test_assert_double_equal( 0.60, ecl_kw_iget_as_double(kwi2, 4) );
ecl_kw_free(kw1);
ecl_kw_free(kw2);
ecl_file_close( ecl_file_index );
}
test_work_area_free( work_area );
}
int main( int argc , char ** argv) {
util_install_signals();
test_load_nonexisting_file();
test_create_and_load_index_file();
}

View File

@@ -72,7 +72,7 @@ void test_alloc_global_only(bool data_in_file) {
test_assert_true( ecl_file_view_has_kw( view_file, TRANNNC_KW) );
test_assert_true(nnc_data_size == 3);
double * values = ecl_nnc_data_get_values( nnc_geo_data );
const double * values = ecl_nnc_data_get_values( nnc_geo_data );
test_assert_double_equal(values[0] , 0);
test_assert_double_equal(values[1] , 1.5);
test_assert_double_equal(values[2] , 3.0);

View File

@@ -17,6 +17,7 @@ namespace ERT {
smspec_node& operator=( const smspec_node& );
smspec_node& operator=( smspec_node&& );
static int cmp( const smspec_node& node1, const smspec_node& node2);
smspec_node(
ecl_smspec_var_type,
const std::string& wgname,

View File

@@ -47,6 +47,9 @@ extern "C" {
typedef struct ecl_file_struct ecl_file_type;
bool ecl_file_load_all( ecl_file_type * ecl_file );
ecl_file_type * ecl_file_open( const char * filename , int flags);
ecl_file_type * ecl_file_fast_open( const char * filename , const char * index_filename , int flags);
bool ecl_file_write_index( const ecl_file_type * ecl_file , const char * index_filename);
bool ecl_file_index_valid(const char * file_name, const char * index_file_name);
void ecl_file_close( ecl_file_type * ecl_file );
void ecl_file_fortio_detach( ecl_file_type * ecl_file );
void ecl_file_free__(void * arg);

View File

@@ -36,8 +36,9 @@ typedef struct inv_map_struct inv_map_type;
inv_map_type * inv_map_alloc(void);
ecl_file_kw_type * inv_map_get_file_kw( inv_map_type * inv_map , const ecl_kw_type * ecl_kw );
void inv_map_free( inv_map_type * map );
bool ecl_file_kw_equal( const ecl_file_kw_type * kw1 , const ecl_file_kw_type * kw2);
ecl_file_kw_type * ecl_file_kw_alloc( const ecl_kw_type * ecl_kw , offset_type offset);
ecl_file_kw_type * ecl_file_kw_alloc0( const char * header , ecl_data_type data_type , int size , offset_type offset);
void ecl_file_kw_free( ecl_file_kw_type * file_kw );
void ecl_file_kw_free__( void * arg );
ecl_kw_type * ecl_file_kw_get_kw( ecl_file_kw_type * file_kw , fortio_type * fortio, inv_map_type * inv_map);
@@ -51,6 +52,10 @@ typedef struct inv_map_struct inv_map_type;
void ecl_file_kw_replace_kw( ecl_file_kw_type * file_kw , fortio_type * target , ecl_kw_type * new_kw );
bool ecl_file_kw_fskip_data( const ecl_file_kw_type * file_kw , fortio_type * fortio);
void ecl_file_kw_inplace_fwrite( ecl_file_kw_type * file_kw , fortio_type * fortio);
void ecl_file_kw_fwrite( const ecl_file_kw_type * file_kw , FILE * stream );
ecl_file_kw_type ** ecl_file_kw_fread_alloc_multiple( FILE * stream , int num);
ecl_file_kw_type * ecl_file_kw_fread_alloc( FILE * stream );
#ifdef __cplusplus
}

View File

@@ -100,6 +100,8 @@ typedef struct ecl_file_view_struct ecl_file_view_type;
const char * ecl_file_view_get_src_file( const ecl_file_view_type * file_view );
void ecl_file_view_fclose_stream( ecl_file_view_type * file_view );
void ecl_file_view_write_index(const ecl_file_view_type * file_view, FILE * ostream);
ecl_file_view_type * ecl_file_view_fread_alloc( fortio_type * fortio , int * flags , inv_map_type * inv_map, FILE * istream );
#ifdef __cplusplus
}

View File

@@ -401,7 +401,7 @@ values (2e20) are denoted with '*'.
#define INTEHEAD_NWGMAX_INDEX 19 // Maximum number of wells in any group
#define INTEHEAD_NGMAXZ_INDEX 20 // Maximum number of groups in field
#define INTEHEAD_NSWELZ_INDEX 25
#define INTEHEAD_NXWELZ_INDEX 26
#define INTEHEAD_NICONZ_INDEX 32 // Number of elements pr completion in the ICON array.
#define INTEHEAD_NSCONZ_INDEX 33 // Number of elements pr completion in the SCON array
#define INTEHEAD_NXCONZ_INDEX 34 // Number of elements pr completion in the XCON array
@@ -591,12 +591,13 @@ values (2e20) are denoted with '*'.
#define GLOBAL_STRING "GLOBAL"
#define GRIDHEAD_TYPE_INDEX 0
#define GRIDHEAD_NX_INDEX 1
#define GRIDHEAD_NY_INDEX 2
#define GRIDHEAD_NZ_INDEX 3
#define GRIDHEAD_LGR_INDEX 4
#define GRIDHEAD_SIZE 100
#define GRIDHEAD_TYPE_INDEX 0
#define GRIDHEAD_NX_INDEX 1
#define GRIDHEAD_NY_INDEX 2
#define GRIDHEAD_NZ_INDEX 3
#define GRIDHEAD_LGR_INDEX 4
#define GRIDHEAD_NUMRES_INDEX 24
#define GRIDHEAD_SIZE 100
/* Observe that these indices are one value lower than the values used
in the ecl_smspec file. */

View File

@@ -54,7 +54,7 @@ typedef struct ecl_smspec_struct ecl_smspec_type;
bool ecl_smspec_needs_wgname( ecl_smspec_var_type var_type );
const char * ecl_smspec_get_var_type_name( ecl_smspec_var_type var_type );
ecl_smspec_var_type ecl_smspec_identify_var_type(const char * var);
ecl_smspec_type * ecl_smspec_alloc_writer( const char * key_join_string , time_t sim_start , bool time_in_days , int nx , int ny , int nz);
ecl_smspec_type * ecl_smspec_alloc_writer( const char * key_join_string , const char * restart_case, time_t sim_start , bool time_in_days , int nx , int ny , int nz);
void ecl_smspec_fwrite( const ecl_smspec_type * smspec , const char * ecl_case , bool fmt_file );
ecl_smspec_type * ecl_smspec_fread_alloc(const char *header_file, const char * key_join_string , bool include_restart);
@@ -143,6 +143,7 @@ typedef struct ecl_smspec_struct ecl_smspec_type;
char * ecl_smspec_alloc_well_key( const ecl_smspec_type * smspec , const char * keyword , const char * wgname);
bool ecl_smspec_equal( const ecl_smspec_type * self , const ecl_smspec_type * other);
void ecl_smspec_sort( ecl_smspec_type * smspec );
#ifdef __cplusplus
}

View File

@@ -18,7 +18,7 @@
*/
#ifndef ERT_ECL_SUBSIDENCE_H
#define ERT_ECL_SUBSICENCE_H
#define ERT_ECL_SUBSIDENCE_H
#ifdef __plusplus
extern "C" {
#endif

View File

@@ -192,6 +192,7 @@ typedef struct ecl_sum_struct ecl_sum_type;
int ecl_sum_iget_report_end( const ecl_sum_type * ecl_sum , int report_step );
int ecl_sum_iget_report_start( const ecl_sum_type * ecl_sum , int report_step );
ecl_sum_type * ecl_sum_alloc_restart_writer( const char * ecl_case , const char * restart_case , bool fmt_output , bool unified , const char * key_join_string , time_t sim_start , bool time_in_days , int nx , int ny , int nz);
ecl_sum_type * ecl_sum_alloc_writer( const char * ecl_case , bool fmt_output , bool unified , const char * key_join_string , time_t sim_start , bool time_in_days , int nx , int ny , int nz);
void ecl_sum_set_case( ecl_sum_type * ecl_sum , const char * ecl_case);
void ecl_sum_fwrite( const ecl_sum_type * ecl_sum );

View File

@@ -21,6 +21,7 @@
#define ERT_SMSPEC_NODE_H
#include <stdbool.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
@@ -39,23 +40,26 @@ extern "C" {
typedef enum {ECL_SMSPEC_INVALID_VAR = 0 ,
ECL_SMSPEC_AQUIFER_VAR = 1 ,
ECL_SMSPEC_WELL_VAR = 2 , /* X */
ECL_SMSPEC_REGION_VAR = 3 , /* X */
ECL_SMSPEC_FIELD_VAR = 4 , /* X */
ECL_SMSPEC_GROUP_VAR = 5 , /* X */
ECL_SMSPEC_FIELD_VAR = 1 , /* X */
ECL_SMSPEC_REGION_VAR = 2 , /* X */
ECL_SMSPEC_GROUP_VAR = 3 , /* X */
ECL_SMSPEC_WELL_VAR = 4 , /* X */
ECL_SMSPEC_SEGMENT_VAR = 5 , /* X */
ECL_SMSPEC_BLOCK_VAR = 6 , /* X */
ECL_SMSPEC_COMPLETION_VAR = 7 , /* X */
ECL_SMSPEC_LOCAL_BLOCK_VAR = 8 , /* X */
ECL_SMSPEC_LOCAL_COMPLETION_VAR = 9 , /* X */
ECL_SMSPEC_LOCAL_WELL_VAR = 10 , /* X */
ECL_SMSPEC_NETWORK_VAR = 11 ,
ECL_SMSPEC_REGION_2_REGION_VAR = 12 ,
ECL_SMSPEC_SEGMENT_VAR = 13 , /* X */
ECL_SMSPEC_AQUIFER_VAR = 7 ,
ECL_SMSPEC_COMPLETION_VAR = 8 , /* X */
ECL_SMSPEC_NETWORK_VAR = 9 ,
ECL_SMSPEC_REGION_2_REGION_VAR = 10 ,
ECL_SMSPEC_LOCAL_BLOCK_VAR = 11 , /* X */
ECL_SMSPEC_LOCAL_COMPLETION_VAR = 12 , /* X */
ECL_SMSPEC_LOCAL_WELL_VAR = 13 , /* X */
ECL_SMSPEC_MISC_VAR = 14 /* X */} ecl_smspec_var_type;
#define SMSPEC_NUMS_INVALID -991199
#define SMSPEC_NUMS_WELL 1
#define SMSPEC_NUMS_GROUP 2
#define SMSPEC_NUMS_FIELD 0
typedef struct smspec_node_struct smspec_node_type;
@@ -75,17 +79,15 @@ typedef enum {ECL_SMSPEC_INVALID_VAR = 0 ,
bool smspec_node_equal( const smspec_node_type * node1, const smspec_node_type * node2);
bool smspec_node_init( smspec_node_type * smspec_node,
ecl_smspec_var_type var_type ,
const char * wgname ,
const char * keyword ,
const char * unit ,
const char * key_join_string ,
const int grid_dims[3] ,
void smspec_node_init( smspec_node_type * smspec_node,
ecl_smspec_var_type var_type ,
const char * wgname ,
const char * keyword ,
const char * unit ,
const char * key_join_string ,
const int grid_dims[3] ,
int num);
smspec_node_type * smspec_node_alloc( ecl_smspec_var_type var_type ,
const char * wgname ,
const char * keyword ,
@@ -123,6 +125,7 @@ typedef enum {ECL_SMSPEC_INVALID_VAR = 0 ,
bool smspec_node_is_rate( const smspec_node_type * smspec_node );
bool smspec_node_is_total( const smspec_node_type * smspec_node );
bool smspec_node_is_historical( const smspec_node_type * smspec_node );
bool smspec_node_is_valid( const smspec_node_type * smspec_node );
bool smspec_node_need_nums( const smspec_node_type * smspec_node );
void smspec_node_fprintf( const smspec_node_type * smspec_node , FILE * stream);
@@ -136,6 +139,9 @@ typedef enum {ECL_SMSPEC_INVALID_VAR = 0 ,
int smspec_node_get_R1( const smspec_node_type * smpsec_node );
int smspec_node_get_R2( const smspec_node_type * smpsec_node );
int smspec_node_cmp( const smspec_node_type * node1, const smspec_node_type * node2);
int smspec_node_cmp__( const void * node1, const void * node2);
#ifdef __cplusplus
}
#endif

View File

@@ -1,76 +0,0 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'block_fs.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 ERT_BLOCK_FS
#define ERT_BLOCK_FS
#include <ert/util/buffer.h>
#include <ert/util/vector.h>
#include <ert/util/type_macros.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct block_fs_struct block_fs_type;
typedef struct user_file_node_struct user_file_node_type;
typedef enum {
NO_SORT = 0,
STRING_SORT = 1,
OFFSET_SORT = 2
} block_fs_sort_type;
size_t block_fs_get_cache_usage( const block_fs_type * block_fs );
double block_fs_get_fragmentation( const block_fs_type * block_fs );
bool block_fs_rotate( block_fs_type * block_fs , double fragmentation_limit);
void block_fs_fsync( block_fs_type * block_fs );
bool block_fs_is_mount( const char * mount_file );
bool block_fs_is_readonly( const block_fs_type * block_fs);
block_fs_type * block_fs_mount( const char * mount_file ,
int block_size ,
int max_cache_size ,
float fragmentation_limit ,
int fsync_interval ,
bool preload ,
bool read_only,
bool use_lockfile);
void block_fs_close( block_fs_type * block_fs , bool unlink_empty);
void block_fs_fwrite_file(block_fs_type * block_fs , const char * filename , const void * ptr , size_t byte_size);
void block_fs_fwrite_buffer(block_fs_type * block_fs , const char * filename , const buffer_type * buffer);
void block_fs_fread_file( block_fs_type * block_fs , const char * filename , void * ptr);
int block_fs_get_filesize( block_fs_type * block_fs , const char * filename);
void block_fs_fread_realloc_buffer( block_fs_type * block_fs , const char * filename , buffer_type * buffer);
void block_fs_sync( block_fs_type * block_fs );
void block_fs_unlink_file( block_fs_type * block_fs , const char * filename);
bool block_fs_has_file( block_fs_type * block_fs , const char * filename);
vector_type * block_fs_alloc_filelist( block_fs_type * block_fs , const char * pattern , block_fs_sort_type sort_mode , bool include_free_nodes );
void block_fs_defrag( block_fs_type * block_fs );
long int user_file_node_get_node_offset( const user_file_node_type * user_file_node );
long int user_file_node_get_data_offset( const user_file_node_type * user_file_node );
int user_file_node_get_node_size( const user_file_node_type * user_file_node );
int user_file_node_get_data_size( const user_file_node_type * user_file_node );
bool user_file_node_in_use( const user_file_node_type * user_file_node );
const char * user_file_node_get_filename( const user_file_node_type * user_file_node );
UTIL_IS_INSTANCE_HEADER( block_fs );
UTIL_SAFE_CAST_HEADER( block_fs );
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -48,9 +48,7 @@ extern "C" {
void buffer_free_container( buffer_type * buffer );
void buffer_free( buffer_type * buffer);
size_t buffer_safe_fread(buffer_type * buffer , void * target_ptr , size_t item_size , size_t items);
size_t buffer_fread(buffer_type * buffer , void * target_ptr , size_t item_size , size_t items);
size_t buffer_safe_fwrite(buffer_type * buffer , const void * src_ptr , size_t item_size , size_t items);
size_t buffer_fwrite(buffer_type * buffer , const void * src_ptr , size_t item_size , size_t items);
void buffer_summarize(const buffer_type * buffer , const char *);

View File

@@ -1,7 +1,7 @@
/*
Copyright (C) 2016 Statoil ASA, Norway.
The file 'ert_version.h' is part of ERT - Ensemble based Reservoir Tool.
The file 'ecl_version.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
@@ -16,8 +16,8 @@
for more details.
*/
#ifndef ERT_VERSION
#define ERT_VERSION
#ifndef ECL_VERSION
#define ECL_VERSION
#include <stdbool.h>
@@ -25,13 +25,13 @@
extern"C" {
#endif
char * version_get_git_commit();
char * version_get_git_commit_short();
char * version_get_build_time();
int version_get_major_ert_version();
int version_get_minor_ert_version();
const char * version_get_micro_ert_version();
bool version_is_ert_devel_version();
const char * ecl_version_get_git_commit();
const char * ecl_version_get_git_commit_short();
const char * ecl_version_get_build_time();
int ecl_version_get_major_version();
int ecl_version_get_minor_version();
const char * ecl_version_get_micro_version();
bool ecl_version_is_ert_devel_version();
#ifdef __cplusplus
}

View File

@@ -25,6 +25,7 @@ extern "C" {
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
//Same as pythons default log levels, but with different numeric values.
typedef enum {

View File

@@ -22,6 +22,10 @@
#include <ert/util/matrix.h>
#ifdef __cplusplus
extern "C" {
#endif //__cplusplus
typedef enum {
LLSQ_SUCCESS = 0,
LLSQ_INVALID_DIM = 1,
@@ -32,5 +36,8 @@ typedef enum {
llsq_result_enum matrix_stat_llsq_estimate( matrix_type * beta , const matrix_type * X , const matrix_type * Y , const matrix_type * S);
llsq_result_enum matrix_stat_polyfit( matrix_type * beta , const matrix_type * X0 , const matrix_type * Y0 , const matrix_type * S);
#ifdef __cplusplus
}
#endif //__cplusplus
#endif

View File

@@ -19,6 +19,10 @@
#ifndef ERT_MENU_H
#define ERT_MENU_H
#ifdef __cplusplus
extern "C" {
#endif //__cplusplus
typedef struct menu_struct menu_type;
typedef struct menu_item_struct menu_item_type;
@@ -40,4 +44,8 @@ void menu_item_disable( menu_item_type * item );
void menu_item_enable( menu_item_type * item );
void menu_add_helptext(menu_type * menu, const char * label );
#ifdef __cplusplus
}
#endif //__cplusplus
#endif

View File

@@ -18,10 +18,12 @@
#ifndef ERT_NODE_DATA_H
#define ERT_NODE_DATA_H
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
typedef void * ( copyc_ftype ) (const void *);
typedef void ( free_ftype ) (void *);

View File

@@ -20,6 +20,10 @@
#define ERT_PARSER_H
#include <ert/util/stringlist.h>
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
typedef struct basic_parser_struct basic_parser_type;
@@ -156,4 +160,9 @@ stringlist_type * basic_parser_tokenize_file(
void basic_parser_strip_buffer(const basic_parser_type * parser , char ** __buffer);
bool basic_parser_fseek_string(const basic_parser_type * parser , FILE * stream , const char * string , bool skip_string , bool case_sensitive);
char * basic_parser_fread_alloc_file_content(const char * filename , const char * quote_set , const char * delete_set , const char * comment_start , const char * comment_end);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif

View File

@@ -18,14 +18,16 @@
#ifndef ERT_PATH_FMT_H
#define ERT_PATH_FMT_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h>
#include <stdbool.h>
#include <ert/util/node_ctype.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct path_fmt_struct path_fmt_type;
path_fmt_type * path_fmt_alloc_directory_fmt(const char * );

View File

@@ -21,6 +21,10 @@
#include <ert/util/type_macros.h>
#ifdef __cplusplus
extern "C" {
#endif //__cplusplus
typedef struct perm_vector_struct perm_vector_type;
perm_vector_type * perm_vector_alloc( int * perm_input , int size );
@@ -28,4 +32,9 @@ void perm_vector_free( perm_vector_type * perm_vector );
int perm_vector_get_size( const perm_vector_type * perm);
int perm_vector_iget( const perm_vector_type * perm, int index);
#ifdef __cplusplus
}
#endif //__cplusplus
#endif

View File

@@ -19,13 +19,11 @@
#ifndef ERT_REGRESSION_H
#define ERT_REGRESSION_H
#include <ert/util/matrix.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <ert/util/matrix.h>
double regression_scale( matrix_type * X , matrix_type * Y , matrix_type * X_mean , matrix_type * X_norm);
double regression_unscale(const matrix_type * beta , const matrix_type * X_norm , const matrix_type * X_mean , double Y_mean , matrix_type * beta0);
void regression_augmented_OLS(const matrix_type * X , const matrix_type * Y , const matrix_type *E, matrix_type * beta);

View File

@@ -18,11 +18,12 @@
#ifndef ERT_STRING_UTIL_H
#define ERT_STRING_UTIL_H
#include <ert/util/int_vector.h>
#include <ert/util/bool_vector.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <ert/util/int_vector.h>
#include <ert/util/bool_vector.h>
bool string_util_init_active_list( const char * range_string , int_vector_type * active_list );
bool string_util_update_active_list( const char * range_string , int_vector_type * active_list );

View File

@@ -18,9 +18,6 @@
#ifndef ERT_STRINGLIST_H
#define ERT_STRINGLIST_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stdio.h>
@@ -30,6 +27,11 @@ extern "C" {
#include <ert/util/int_vector.h>
#include <ert/util/buffer.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct stringlist_struct stringlist_type;
typedef int ( string_cmp_ftype) (const void * , const void *);

View File

@@ -1,69 +0,0 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'subst_list.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 ERT_SUBST_H
#define ERT_SUBST_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdbool.h>
#include <ert/util/type_macros.h>
#include <ert/util/subst_func.h>
typedef struct subst_list_struct subst_list_type;
bool subst_list_update_buffer( const subst_list_type * subst_list , buffer_type * buffer );
void subst_list_insert_func(subst_list_type * subst_list , const char * func_name , const char * local_func_name);
void subst_list_fprintf(const subst_list_type * , FILE * stream);
void subst_list_set_parent( subst_list_type * subst_list , const subst_list_type * parent);
const subst_list_type * subst_list_get_parent( const subst_list_type * subst_list );
subst_list_type * subst_list_alloc( const void * input_arg );
subst_list_type * subst_list_alloc_deep_copy(const subst_list_type * );
void subst_list_free(subst_list_type *);
void subst_list_clear( subst_list_type * subst_list );
void subst_list_append_copy(subst_list_type * , const char * , const char * , const char * doc_string);
void subst_list_append_ref(subst_list_type * , const char * , const char * , const char * doc_string);
void subst_list_append_owned_ref(subst_list_type * , const char * , const char * , const char * doc_string);
void subst_list_prepend_copy(subst_list_type * , const char * , const char * , const char * doc_string);
void subst_list_prepend_ref(subst_list_type * , const char * , const char * , const char * doc_string);
void subst_list_prepend_owned_ref(subst_list_type * , const char * , const char * , const char * doc_string);
bool subst_list_filter_file(const subst_list_type * , const char * , const char * );
bool subst_list_update_file(const subst_list_type * , const char * );
bool subst_list_update_string(const subst_list_type * , char ** );
char * subst_list_alloc_filtered_string(const subst_list_type * , const char * );
void subst_list_filtered_fprintf(const subst_list_type * , const char * , FILE * );
int subst_list_get_size( const subst_list_type *);
const char * subst_list_get_value( const subst_list_type * subst_list , const char * key);
const char * subst_list_iget_value( const subst_list_type * subst_list , int index);
const char * subst_list_iget_key( const subst_list_type * subst_list , int index);
const char * subst_list_iget_doc_string( const subst_list_type * subst_list , int index);
bool subst_list_has_key( const subst_list_type * subst_list , const char * key);
char * subst_list_alloc_string_representation( const subst_list_type * subst_list );
int subst_list_add_from_string( subst_list_type * subst_list , const char * arg_string, bool append);
UTIL_IS_INSTANCE_HEADER( subst_list );
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,48 +0,0 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'template.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 ERT_UTIL_TEMPLATE_H
#define ERT_UTIL_TEMPLATE_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <ert/util/subst_list.h>
typedef struct template_struct template_type;
template_type * template_alloc( const char * template_file , bool internalize_template, subst_list_type * parent_subst);
void template_free( template_type * template );
void template_instantiate( const template_type * template , const char * __target_file , const subst_list_type * arg_list , bool override_symlink);
void template_add_arg( template_type * template , const char * key , const char * value );
void template_clear_args( template_type * template );
int template_add_args_from_string( template_type * template , const char * arg_string);
char * template_get_args_as_string( template_type * template );
void template_set_template_file( template_type * template , const char * template_file);
const char * template_get_template_file( const template_type * template );
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -18,13 +18,14 @@
#ifndef ERT_TYPE_VECTOR_FUNCTIONS_H
#define ERT_TYPE_VECTOR_FUNCTIONS_H
#ifdef __cplusplus
extern "C" {
#endif
#include <ert/util/int_vector.h>
#include <ert/util/bool_vector.h>
#include <ert/util/double_vector.h>
#ifdef __cplusplus
extern "C" {
#endif
int_vector_type * bool_vector_alloc_active_list( const bool_vector_type * mask );
bool_vector_type * int_vector_alloc_mask( const int_vector_type * active_list );
int_vector_type * bool_vector_alloc_active_index_list(const bool_vector_type * mask , int default_value);

View File

@@ -19,14 +19,14 @@
#ifndef ERT_UI_RETURN_H
#define ERT_UI_RETURN_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <ert/util/type_macros.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ui_return_struct ui_return_type;

View File

@@ -231,7 +231,7 @@ typedef enum {left_pad = 0,
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);
bool util_sscanf_octal_int(const char * buffer , 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 * );
@@ -285,9 +285,7 @@ typedef enum {left_pad = 0,
bool util_is_first_day_in_month_utc( time_t t);
void util_fread_from_buffer(void * , size_t , size_t , char ** );
unsigned int util_dev_urandom_seed( );
unsigned int util_clock_seed( void );
void util_fread_dev_random(int , char * );
void util_fread_dev_urandom(int , char * );
@@ -351,6 +349,8 @@ typedef enum {left_pad = 0,
long util_fread_long(FILE * );
bool util_fread_bool(FILE * );
double util_fread_double(FILE * stream);
void util_fwrite_offset(offset_type , FILE * );
void util_fwrite_size_t (size_t , FILE * );
void util_fwrite_int (int , FILE * );
void util_fwrite_long (long , FILE * );
void util_fwrite_bool (bool , FILE * );
@@ -531,9 +531,7 @@ void util_abort_set_executable( const char * argv0 );
bool util_try_lockf(const char * , mode_t , int * );
#endif
#include "util_unlink.h"
#ifdef __cplusplus
}

View File

@@ -0,0 +1,34 @@
/*
Copyright (C) 2017 Statoil ASA, Norway.
The file 'util_unlink.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 ERT_UTIL_UNLINK_H
#define ERT_UTIL_UNLINK_H
#ifdef __cplusplus
extern "C" {
#endif
int util_unlink(const char * filename);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -19,13 +19,14 @@
#ifndef ERT_VECTOR_H
#define ERT_VECTOR_H
#ifdef __cplusplus
extern "C" {
#endif
#include <ert/util/node_data.h>
#include <ert/util/type_macros.h>
#include <ert/util/int_vector.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void ( vector_func_type ) (void * , void *);
typedef int ( vector_cmp_ftype) (const void * , const void *);
@@ -76,6 +77,7 @@ extern "C" {
void * vector_pop_front(vector_type * );
void vector_sort(vector_type * vector , vector_cmp_ftype * cmp);
int_vector_type * vector_alloc_sort_perm(const vector_type * vector , vector_cmp_ftype * cmp);
void vector_permute(vector_type * vector , const int_vector_type * perm_vector);
void vector_inplace_reverse(vector_type * vector);
vector_type * vector_alloc_copy(const vector_type * src , bool deep_copy);

View File

@@ -112,7 +112,7 @@ struct arg_pack_struct {
/* First comes the arg_node functions. These are all fully static.*/
static arg_node_type * arg_node_alloc_empty() {
arg_node_type * node = util_malloc( sizeof * node );
arg_node_type * node = (arg_node_type*)util_malloc( sizeof * node );
node->buffer = NULL;
node->destructor = NULL;
node->ctype = CTYPE_INVALID;
@@ -344,7 +344,7 @@ static void __arg_pack_assert_index(const arg_pack_type * arg , int iarg) {
static void arg_pack_realloc_nodes(arg_pack_type * arg_pack , int new_size) {
arg_pack->nodes = util_realloc(arg_pack->nodes , new_size * sizeof * arg_pack->nodes );
arg_pack->nodes = (arg_node_type**) util_realloc(arg_pack->nodes , new_size * sizeof * arg_pack->nodes );
{
int i;
for (i = arg_pack->alloc_size; i < new_size; i++)
@@ -400,7 +400,7 @@ void arg_pack_lock(arg_pack_type * arg_pack) {
arg_pack_type * arg_pack_alloc() {
arg_pack_type * arg_pack = util_malloc(sizeof * arg_pack );
arg_pack_type * arg_pack = (arg_pack_type*)util_malloc(sizeof * arg_pack );
UTIL_TYPE_ID_INIT( arg_pack , ARG_PACK_TYPE_ID);
arg_pack->nodes = NULL;
arg_pack->alloc_size = 0;

File diff suppressed because it is too large Load Diff

View File

@@ -85,12 +85,12 @@ UTIL_SAFE_CAST_FUNCTION( buffer , BUFFER_TYPE_ID )
static void buffer_resize__(buffer_type * buffer , size_t new_size, bool abort_on_error) {
if (abort_on_error) {
buffer->data = util_realloc(buffer->data , new_size );
buffer->data = (char*)util_realloc(buffer->data , new_size );
buffer->alloc_size = new_size;
} else {
void * tmp = realloc(buffer->data , new_size);
if (tmp != NULL) {
buffer->data = tmp;
buffer->data = (char*)tmp;
buffer->alloc_size = new_size;
}
}
@@ -100,7 +100,7 @@ static void buffer_resize__(buffer_type * buffer , size_t new_size, bool abort_o
static buffer_type * buffer_alloc_empty( ) {
buffer_type * buffer = util_malloc( sizeof * buffer );
buffer_type * buffer = (buffer_type*)util_malloc( sizeof * buffer );
UTIL_TYPE_ID_INIT( buffer , BUFFER_TYPE_ID );
buffer->data = NULL;
@@ -142,7 +142,7 @@ void buffer_shrink_to_fit( buffer_type * buffer ) {
buffer_type * buffer_alloc_private_wrapper(void * data , size_t buffer_size ) {
buffer_type * buffer = buffer_alloc_empty();
buffer->data = data; /* We have stolen the data pointer. */
buffer->data = (char*)data; /* We have stolen the data pointer. */
buffer->content_size = buffer_size;
buffer->pos = buffer_size;
buffer->alloc_size = buffer_size;
@@ -194,98 +194,52 @@ void buffer_clear( buffer_type * buffer ) {
}
/*****************************************************************/
/**
Observe that it is the functions with _safe_ in the name which
most closely mimicks the behaviour of fread(), and fwrite() -
these functions will *NOT* abort if the buffer is to small,
instead they will just return the number of items read/written,
and it is the responsability of the calling scope to check the
return values.
The functions buffer_fread() and buffer_fwrite() will abort if
read/write to buffer failed.
*/
static size_t buffer_fread__(buffer_type * buffer , void * target_ptr , size_t item_size , size_t items, bool abort_on_error) {
size_t buffer_fread(buffer_type * buffer,
void * target_ptr,
size_t item_size,
size_t items) {
size_t remaining_size = buffer->content_size - buffer->pos;
size_t remaining_items = remaining_size / item_size;
size_t read_items = util_size_t_min( items , remaining_items );
size_t read_bytes = read_items * item_size;
if (remaining_items < items)
util_abort("%s: read beyond the length of the buffer (%d exceeds %d)\n",
__func__, items, remaining_items);
memcpy( target_ptr , &buffer->data[buffer->pos] , read_bytes );
size_t read_bytes = items * item_size;
memcpy(target_ptr, &buffer->data[buffer->pos], read_bytes);
buffer->pos += read_bytes;
if (read_items < items) {
/* The buffer was not large enough - what to do now???? */
if (abort_on_error)
util_abort("%s: tried to read beyond the length of the buffer: Wanted:%ld Size:%ld \n",__func__ , items , read_items);
else
/* OK we emulate fread() behaviour - setting errno to EOVERFLOW*/
errno = ENOMEM;//EOVERFLOW;
}
return read_items;
}
size_t buffer_safe_fread(buffer_type * buffer , void * target_ptr , size_t item_size , size_t items) {
return buffer_fread__(buffer , target_ptr , item_size , items , false);
}
size_t buffer_fread(buffer_type * buffer , void * target_ptr , size_t item_size , size_t items) {
return buffer_fread__(buffer , target_ptr , item_size , items , true);
return items;
}
/*****************************************************************/
static size_t buffer_fwrite__(buffer_type * buffer , const void * src_ptr , size_t item_size , size_t items, bool abort_on_error) {
size_t remaining_size = buffer->alloc_size - buffer->pos;
size_t target_size = item_size * items;
size_t buffer_fwrite(buffer_type * buffer,
const void * src_ptr,
size_t item_size,
size_t items) {
size_t remaining_size = buffer->alloc_size - buffer->pos;
size_t target_size = item_size * items;
if (target_size > remaining_size) {
buffer_resize__(buffer , buffer->pos + 2 * (item_size * items) , abort_on_error);
/**
OK - now we have the buffer size we are going to get.
*/
buffer_resize__(buffer , buffer->pos + 2 * (item_size * items), true);
remaining_size = buffer->alloc_size - buffer->pos;
}
size_t remaining_items = remaining_size / item_size;
size_t write_items = util_size_t_min( items , remaining_items );
size_t write_bytes = write_items * item_size;
{
size_t remaining_items = remaining_size / item_size;
size_t write_items = util_size_t_min( items , remaining_items );
size_t write_bytes = write_items * item_size;
memcpy( &buffer->data[buffer->pos] , src_ptr , write_bytes );
buffer->pos += write_bytes;
memcpy( &buffer->data[buffer->pos] , src_ptr , write_bytes );
buffer->pos += write_bytes;
if (write_items < items) {
/* The buffer was not large enough - what to do now???? */
if (abort_on_error)
util_abort("%s: failed to write %d elements to the buffer \n",__func__ , items); /* This code is never executed - abort is in resize__(); */
else
/* OK we emulate fwrite() behaviour - setting errno to ENOMEM */
errno = ENOMEM;
}
buffer->content_size = util_size_t_max(buffer->content_size , buffer->pos);
return write_items;
}
}
size_t buffer_safe_fwrite(buffer_type * buffer , const void * src_ptr , size_t item_size , size_t items) {
return buffer_fwrite__(buffer , src_ptr , item_size , items , false);
}
size_t buffer_fwrite(buffer_type * buffer , const void * src_ptr , size_t item_size , size_t items) {
return buffer_fwrite__(buffer , src_ptr , item_size , items , true);
if (write_items < items)
util_abort("%s: failed to write %d elements to the buffer \n",__func__ , items);
buffer->content_size = util_size_t_max(buffer->content_size , buffer->pos);
return write_items;
}
@@ -321,7 +275,8 @@ void buffer_fseek(buffer_type * buffer , ssize_t offset , int whence) {
if ((new_pos >= 0) && (new_pos <= buffer->content_size))
buffer->pos = new_pos;
else
util_abort("%s: tried to seek to position:%ld - outside of bounds: [0,%d) \n",__func__ , new_pos , buffer->content_size);
util_abort("%s: tried to seek to position:%ld - outside of bounds: [0,%d) \n",
__func__ , new_pos , buffer->content_size);
}
@@ -331,34 +286,36 @@ void buffer_fskip(buffer_type * buffer, ssize_t offset) {
int buffer_fread_int(buffer_type * buffer) {
int value;
buffer_fread(buffer , &value , sizeof value , 1);
int value = 0;
int read = buffer_fread(buffer, &value, sizeof value, 1);
if (read != 1)
util_abort("%s: read mismatch, read %d expected to read %d\n",
__func__, read, 1);
return value;
}
bool buffer_fread_bool(buffer_type * buffer) {
bool value;
buffer_fread(buffer , &value , sizeof value , 1);
bool value = false;
buffer_fread(buffer, &value, sizeof value, 1);
return value;
}
long int buffer_fread_long(buffer_type * buffer) {
long value;
buffer_fread(buffer , &value , sizeof value , 1);
long value = 0L;
buffer_fread(buffer, &value, sizeof value, 1);
return value;
}
int buffer_fgetc( buffer_type * buffer ) {
int buffer_fgetc(buffer_type * buffer) {
if (buffer->pos == buffer->content_size)
return EOF;
else {
unsigned char byte;
buffer_fread( buffer , &byte , sizeof byte , 1 );
return byte;
}
unsigned char byte = 0;
buffer_fread(buffer, &byte, sizeof byte, 1);
return byte;
}
/**
@@ -572,8 +529,8 @@ void buffer_memshift(buffer_type * buffer , size_t offset, ssize_t shift) {
{
size_t move_size;
if (shift < 0)
if (abs(shift) > offset)
offset = abs(shift); /* We are 'trying' to left shift beyond the start of the buffer. */
if (labs(shift) > offset)
offset = labs(shift); /* We are 'trying' to left shift beyond the start of the buffer. */
move_size = buffer->content_size - offset;
memmove( &buffer->data[offset + shift] , &buffer->data[offset] , move_size );
@@ -763,7 +720,7 @@ buffer_type * buffer_fread_alloc(const char * filename) {
*/
size_t buffer_stream_fwrite_n( const buffer_type * buffer , size_t offset , ssize_t write_size , FILE * stream ) {
if (offset < 0 || offset > buffer->content_size)
if (offset > buffer->content_size)
util_abort("%s: invalid offset:%ld - valid range: [0,%ld) \n",__func__ , offset , offset);
{
ssize_t len;
@@ -773,7 +730,7 @@ size_t buffer_stream_fwrite_n( const buffer_type * buffer , size_t offset , ssiz
else if (write_size == 0) /* Write everything from the offset */
len = buffer->content_size - offset;
else /* @write_size < 0 - write everything excluding the last abs(write_size) bytes. */
len = buffer->content_size - offset - abs( write_size );
len = buffer->content_size - offset - labs( write_size );
if (len < 0)
util_abort("%s: invalid length spesifier - tried to write %ld bytes \n",__func__ , len);
@@ -912,7 +869,7 @@ size_t buffer_fread_compressed(buffer_type * buffer , size_t compressed_size , v
if (compressed_size > 0) {
int uncompress_result = uncompress(target_ptr , &uncompressed_size , (unsigned char *) &buffer->data[buffer->pos] , compressed_size);
int uncompress_result = uncompress((Bytef*)target_ptr , &uncompressed_size , (unsigned char *) &buffer->data[buffer->pos] , compressed_size);
if (uncompress_result != Z_OK) {
fprintf(stderr,"%s: ** Warning uncompress result:%d != Z_OK.\n" , __func__ , uncompress_result);
/**

49
ThirdParty/Ert/lib/util/ecl_version.c vendored Normal file
View File

@@ -0,0 +1,49 @@
#include <ert/util/util.h>
#include <ert/util/ecl_version.h>
#define xstr(s) #s
#define str(s) xstr(s)
const char* ecl_version_get_git_commit() {
#ifdef GIT_COMMIT
return str(GIT_COMMIT);
#else
return "Unknown git commit hash";
#endif
}
const char* ecl_version_get_git_commit_short() {
#ifdef GIT_COMMIT_SHORT
return str(GIT_COMMIT_SHORT);
#else
return "Unknown git short commit hash";
#endif
}
const char* ecl_version_get_build_time() {
#ifdef COMPILE_TIME_STAMP
return COMPILE_TIME_STAMP;
#else
return "Unknown build time";
#endif
}
int ecl_version_get_major_version() {
return ECL_VERSION_MAJOR;
}
int ecl_version_get_minor_version() {
return ECL_VERSION_MINOR;
}
const char * ecl_version_get_micro_version() {
return str(ECL_VERSION_MICRO);
}
bool ecl_version_is_devel_version() {
return util_sscanf_int(str(ECL_VERSION_MICRO), NULL);
}

View File

@@ -1,49 +0,0 @@
#include <ert/util/util.h>
#include <ert/util/ert_version.h>
#define xstr(s) #s
#define str(s) xstr(s)
char* version_get_git_commit() {
#ifdef GIT_COMMIT
return str(GIT_COMMIT);
#else
return "Unknown git commit hash";
#endif
}
char* version_get_git_commit_short() {
#ifdef GIT_COMMIT_SHORT
return str(GIT_COMMIT_SHORT);
#else
return "Unknown git short commit hash";
#endif
}
char* version_get_build_time() {
#ifdef COMPILE_TIME_STAMP
return COMPILE_TIME_STAMP;
#else
return "Unknown build time";
#endif
}
int version_get_major_ert_version() {
return ERT_VERSION_MAJOR;
}
int version_get_minor_ert_version() {
return ERT_VERSION_MINOR;
}
const char * version_get_micro_ert_version() {
return str(ERT_VERSION_MICRO);
}
bool version_is_ert_devel_version() {
return util_sscanf_int(str(ERT_VERSION_MICRO), NULL);
}

View File

@@ -87,10 +87,6 @@ typedef struct hash_sort_node {
/* locking */
/*****************************************************************/
#ifdef HAVE_PTHREAD
static void __hash_deadlock_abort(hash_type * hash) {
util_abort("%s: A deadlock condition has been detected in the hash routine - and the program will abort.\n", __func__);
}
static void __hash_rdlock(hash_type * hash) {
int lock_error = pthread_rwlock_tryrdlock( &hash->rwlock );
@@ -163,14 +159,14 @@ static void * __hash_get_node(const hash_type *hash_in , const char *key, bool a
hash_node_type * node;
hash_type * hash = (hash_type *)hash_in;
__hash_rdlock( hash );
node = __hash_get_node_unlocked(hash , key , abort_on_error);
node = (hash_node_type*)__hash_get_node_unlocked(hash , key , abort_on_error);
__hash_unlock( hash );
return node;
}
static node_data_type * hash_get_node_data(const hash_type *hash , const char *key) {
hash_node_type * node = __hash_get_node(hash , key , true);
hash_node_type * node = (hash_node_type*)__hash_get_node(hash , key , true);
return hash_node_get_data(node);
}
@@ -233,7 +229,7 @@ static void __hash_insert_node(hash_type *hash , hash_node_type *node) {
If a node with the same key already exists in the table
it is removed.
*/
hash_node_type *existing_node = __hash_get_node_unlocked(hash , hash_node_get_key(node) , false);
hash_node_type *existing_node = (hash_node_type*)__hash_get_node_unlocked(hash , hash_node_get_key(node) , false);
if (existing_node != NULL) {
hash_sll_del_node(hash->table[table_index] , existing_node);
hash->elements--;
@@ -316,7 +312,7 @@ static char ** hash_alloc_keylist__(hash_type *hash , bool lock) {
if (hash->elements > 0) {
int i = 0;
hash_node_type *node = NULL;
keylist = calloc(hash->elements , sizeof *keylist);
keylist = (char**)calloc(hash->elements , sizeof *keylist);
{
uint32_t i = 0;
while (i < hash->size && hash_sll_empty(hash->table[i]))
@@ -461,8 +457,8 @@ void hash_clear(hash_type *hash) {
void * hash_get(const hash_type *hash , const char *key) {
hash_node_type * hash_node = __hash_get_node(hash , key , true);
node_data_type * data_node = hash_node_get_data( hash_node );
hash_node_type * hash_node = (hash_node_type*)__hash_get_node(hash , key , true);
node_data_type * data_node = (node_data_type*)hash_node_get_data( hash_node );
return node_data_get_ptr( data_node );
}
@@ -472,7 +468,7 @@ void * hash_get(const hash_type *hash , const char *key) {
contain 'key'.
*/
void * hash_safe_get( const hash_type * hash , const char * key ) {
hash_node_type * hash_node = __hash_get_node(hash , key , false);
hash_node_type * hash_node = (hash_node_type*)__hash_get_node(hash , key , false);
if (hash_node != NULL) {
node_data_type * data_node = hash_node_get_data( hash_node );
return node_data_get_ptr( data_node );
@@ -509,7 +505,7 @@ void * hash_pop( hash_type * hash , const char * key) {
static hash_type * __hash_alloc(int size, double resize_fill , hashf_type *hashf) {
hash_type* hash;
hash = util_malloc(sizeof *hash );
hash = (hash_type*)util_malloc(sizeof *hash );
UTIL_TYPE_ID_INIT(hash , HASH_TYPE_ID);
hash->size = size;
hash->hashf = hashf;
@@ -660,7 +656,7 @@ int hash_get_size(const hash_type *hash) {
static hash_sort_type * hash_alloc_sort_list(const hash_type *hash ,
const char **keylist) {
int i; hash_sort_type * sort_list = calloc(hash_get_size(hash) , sizeof * sort_list);
int i; hash_sort_type * sort_list = (hash_sort_type*)calloc(hash_get_size(hash) , sizeof * sort_list);
for (i=0; i < hash_get_size(hash); i++)
sort_list[i].key = util_alloc_string_copy(keylist[i]);
@@ -698,7 +694,7 @@ static char ** __hash_alloc_ordered_keylist(hash_type *hash , int ( hash_get_cmp
sort_list[i].cmp_value = hash_get_cmp_value( hash_get(hash , sort_list[i].key) );
qsort(sort_list , hash_get_size(hash) , sizeof *sort_list , &hash_sortlist_cmp);
sorted_keylist = calloc(hash_get_size(hash) , sizeof *sorted_keylist);
sorted_keylist = (char**)calloc(hash_get_size(hash) , sizeof *sorted_keylist);
for (i = 0; i < hash_get_size(hash); i++) {
sorted_keylist[i] = util_alloc_string_copy(sort_list[i].key);
free(tmp_keylist[i]);
@@ -865,7 +861,7 @@ void hash_iter_restart( hash_iter_type * iter ) {
hash_iter_type * hash_iter_alloc(const hash_type * hash) {
hash_iter_type * iter = util_malloc(sizeof * iter );
hash_iter_type * iter = (hash_iter_type*)util_malloc(sizeof * iter );
iter->hash = hash;
iter->num_keys = hash_get_size(hash);

View File

@@ -92,7 +92,7 @@ node_data_type * hash_node_get_data(const hash_node_type * node) {
hash_node_type * hash_node_alloc_new(const char *key, node_data_type * data, hashf_type *hashf , uint32_t table_size) {
hash_node_type *node;
node = util_malloc(sizeof *node );
node = (hash_node_type*) util_malloc(sizeof *node );
node->key = util_alloc_string_copy( key );
node->data = data;
node->next_node = NULL;

View File

@@ -35,7 +35,7 @@ struct hash_sll_struct {
static hash_sll_type * hash_sll_alloc( void ) {
hash_sll_type * hash_sll = util_malloc(sizeof * hash_sll );
hash_sll_type * hash_sll = (hash_sll_type*) util_malloc(sizeof * hash_sll );
hash_sll->length = 0;
hash_sll->head = NULL;
return hash_sll;
@@ -43,7 +43,7 @@ static hash_sll_type * hash_sll_alloc( void ) {
hash_sll_type ** hash_sll_alloc_table(int size) {
hash_sll_type ** table = util_malloc(size * sizeof * table );
hash_sll_type ** table = (hash_sll_type**) util_malloc(size * sizeof * table );
int i;
for (i=0; i<size; i++)
table[i] = hash_sll_alloc();

View File

@@ -48,7 +48,7 @@ struct lars_struct {
static lars_type * lars_alloc__() {
lars_type * lars = util_malloc( sizeof * lars );
lars_type * lars = (lars_type*)util_malloc( sizeof * lars );
UTIL_TYPE_ID_INIT( lars , LARS_TYPE_ID );
lars->X = NULL;
lars->Y = NULL;

View File

@@ -103,7 +103,7 @@ void log_set_level( log_type * logh , int log_level) {
log_type * log_open( const char * filename , int log_level) {
log_type *logh;
logh = util_malloc(sizeof *logh );
logh = (log_type*)util_malloc(sizeof *logh );
logh->log_level = log_level;
logh->filename = NULL;

View File

@@ -111,7 +111,7 @@ bool lookup_table_has_high_limit(const lookup_table_type * lt ) {
lookup_table_type * lookup_table_alloc( double_vector_type * x , double_vector_type * y , bool data_owner) {
lookup_table_type * lt = util_malloc( sizeof * lt);
lookup_table_type * lt = (lookup_table_type*)util_malloc( sizeof * lt);
lt->data_owner = false;
if ((x == NULL) && (y == NULL)) {
x = double_vector_alloc(0 , 0);

View File

@@ -134,9 +134,9 @@ static void matrix_realloc_data__( matrix_type * matrix , bool safe_mode ) {
otherwise we use util_malloc() which will abort if the memory
is not available.
*/
matrix->data = malloc( sizeof * matrix->data * data_size );
matrix->data = (double*)malloc( sizeof * matrix->data * data_size );
} else
matrix->data = util_malloc( sizeof * matrix->data * data_size );
matrix->data = (double*)util_malloc( sizeof * matrix->data * data_size );
/* Initializing matrix content to zero. */
@@ -163,7 +163,7 @@ UTIL_SAFE_CAST_FUNCTION( matrix , MATRIX_TYPE_ID )
The matrix objecty is NOT ready for use after this function.
*/
static matrix_type * matrix_alloc_empty( ) {
matrix_type * matrix = util_malloc( sizeof * matrix );
matrix_type * matrix = (matrix_type*)util_malloc( sizeof * matrix );
UTIL_TYPE_ID_INIT( matrix , MATRIX_TYPE_ID );
matrix->name = NULL;
return matrix;
@@ -1072,7 +1072,7 @@ matrix_type * matrix_alloc_transpose( const matrix_type * A) {
void matrix_inplace_matmul(matrix_type * A, const matrix_type * B) {
if ((A->columns == B->rows) && (B->rows == B->columns)) {
double * tmp = util_malloc( sizeof * A->data * A->columns );
double * tmp = (double*)util_malloc( sizeof * A->data * A->columns );
int i,j,k;
for (i=0; i < A->rows; i++) {
@@ -1108,10 +1108,10 @@ void matrix_inplace_matmul(matrix_type * A, const matrix_type * B) {
static void * matrix_inplace_matmul_mt__(void * arg) {
arg_pack_type * arg_pack = arg_pack_safe_cast( arg );
int row_offset = arg_pack_iget_int( arg_pack , 0 );
int rows = arg_pack_iget_int( arg_pack , 1 );
matrix_type * A = arg_pack_iget_ptr( arg_pack , 2 );
const matrix_type * B = arg_pack_iget_const_ptr( arg_pack , 3 );
int row_offset = arg_pack_iget_int( arg_pack , 0 );
int rows = arg_pack_iget_int( arg_pack , 1 );
matrix_type * A = (matrix_type*) arg_pack_iget_ptr( arg_pack , 2 );
const matrix_type * B = (const matrix_type*)arg_pack_iget_const_ptr( arg_pack , 3 );
matrix_type * A_view = matrix_alloc_shared( A , row_offset , 0 , rows , matrix_get_columns( A ));
matrix_inplace_matmul( A_view , B );
@@ -1136,7 +1136,7 @@ static void * matrix_inplace_matmul_mt__(void * arg) {
void matrix_inplace_matmul_mt2(matrix_type * A, const matrix_type * B , thread_pool_type * thread_pool){
int num_threads = thread_pool_get_max_running( thread_pool );
arg_pack_type ** arglist = util_malloc( num_threads * sizeof * arglist );
arg_pack_type ** arglist = (arg_pack_type**)util_malloc( num_threads * sizeof * arglist );
int it;
thread_pool_restart( thread_pool );
{

View File

@@ -87,7 +87,7 @@ void matrix_dgesv(matrix_type * A , matrix_type * B) {
int lda = matrix_get_column_stride( A );
int ldb = matrix_get_column_stride( B );
int nrhs = matrix_get_columns( B );
long int * ipivot = util_calloc( n , sizeof * ipivot );
long int * ipivot = (long int*)util_calloc( n , sizeof * ipivot );
int info;
dgesv_(&n , &nrhs , matrix_get_data( A ) , &lda , ipivot , matrix_get_data( B ), &ldb , &info);
@@ -183,7 +183,7 @@ void matrix_dgesvd(dgesvd_vector_enum jobu , dgesvd_vector_enum jobvt , matrix_
Query the routine for optimal worksize.
*/
work = util_calloc( 1 , sizeof * work );
work = (double*)util_calloc( 1 , sizeof * work );
worksize = -1;
dgesvd_(&_jobu , /* 1 */
&_jobvt , /* 2 */
@@ -203,12 +203,12 @@ void matrix_dgesvd(dgesvd_vector_enum jobu , dgesvd_vector_enum jobvt , matrix_
/* Try to allocate optimal worksize. */
worksize = (int) work[0];
double * tmp = realloc( work , sizeof * work * worksize );
double * tmp = (double*)realloc( work , sizeof * work * worksize );
if (tmp == NULL) {
/* Could not allocate optimal worksize - settle for the minimum. This can not fail. */
worksize = min_worksize;
free(work);
work = util_calloc( worksize , sizeof * work );
work = (double*)util_calloc( worksize , sizeof * work );
}else{
work = tmp; /* The request for optimal worksize succeeded */
}
@@ -273,9 +273,9 @@ int matrix_dsyevx(bool compute_eig_vectors ,
{
int num_eigenvalues , ldz, info , worksize;
int * ifail = util_calloc( n , sizeof * ifail );
int * iwork = util_calloc( 5 * n , sizeof * iwork );
double * work = util_calloc( 1 , sizeof * work );
int * ifail = (int*) util_calloc( n , sizeof * ifail );
int * iwork = (int*) util_calloc( 5 * n , sizeof * iwork );
double * work = (double*)util_calloc( 1 , sizeof * work );
double * z_data;
double abstol = 0.0; /* SHopuld */
@@ -316,14 +316,14 @@ int matrix_dsyevx(bool compute_eig_vectors ,
worksize = (int) work[0];
{
double * tmp = realloc(work , sizeof * work * worksize );
double * tmp = (double*)realloc(work , sizeof * work * worksize );
if (tmp == NULL) {
/*
OK - we could not get the optimal worksize,
try again with the minimum.
*/
worksize = 8 * n;
work = util_realloc(work , sizeof * work * worksize );
work = (double*)util_realloc(work , sizeof * work * worksize );
} else
work = tmp; /* The request for optimal worksize succeeded */
}
@@ -382,7 +382,7 @@ void matrix_dgeqrf(matrix_type * A , double * tau) {
int lda = matrix_get_column_stride( A );
int m = matrix_get_rows( A );
int n = matrix_get_columns( A );
double * work = util_calloc(1 , sizeof * work );
double * work = (double*)util_calloc(1 , sizeof * work );
int worksize;
int info;
@@ -394,14 +394,14 @@ void matrix_dgeqrf(matrix_type * A , double * tau) {
util_abort("%s: dgerqf routine failed with info:%d \n",__func__ , info);
worksize = ( int ) work[0];
{
double * tmp = realloc(work , sizeof * work * worksize );
double * tmp = (double*)realloc(work , sizeof * work * worksize );
if (tmp == NULL) {
/*
OK - we could not get the optimal worksize,
try again with the minimum.
*/
worksize = n;
work = util_realloc(work , sizeof * work * worksize );
work = (double*)util_realloc(work , sizeof * work * worksize );
} else
work = tmp; /* The request for optimal worksize succeeded */
}
@@ -423,7 +423,7 @@ void matrix_dorgqr(matrix_type * A , double * tau, int num_reflectors) { /* num
int lda = matrix_get_column_stride( A );
int m = matrix_get_rows( A );
int n = matrix_get_columns( A );
double * work = util_malloc(sizeof * work );
double * work = (double*)util_malloc(sizeof * work );
int worksize;
int info;
@@ -435,14 +435,14 @@ void matrix_dorgqr(matrix_type * A , double * tau, int num_reflectors) { /* num
util_abort("%s: dorgqf routine failed with info:%d \n",__func__ , info);
worksize = ( int ) work[0];
{
double * tmp = realloc(work , sizeof * work * worksize );
double * tmp = (double*)realloc(work , sizeof * work * worksize );
if (tmp == NULL) {
/*
OK - we could not get the optimal worksize,
try again with the minimum.
*/
worksize = n;
work = util_realloc(work , sizeof * work * worksize );
work = (double*)util_realloc(work , sizeof * work * worksize );
} else
work = tmp; /* The request for optimal worksize succeeded */
}
@@ -483,7 +483,7 @@ double matrix_det( matrix_type *A ) {
double det = 1;
double det_scale = 0;
int n = matrix_get_columns( A );
int * ipiv = util_malloc( n * sizeof * ipiv );
int * ipiv = (int*)util_malloc( n * sizeof * ipiv );
matrix_dgetrf__( A , ipiv , &dgetrf_info );
{
int i;
@@ -537,11 +537,11 @@ int matrix_inv( matrix_type * A ) {
int dgetrf_info;
int info;
int n = matrix_get_columns( A );
int * ipiv = util_malloc( n * sizeof * ipiv );
int * ipiv = (int*)util_malloc( n * sizeof * ipiv );
matrix_dgetrf__( A , ipiv , &dgetrf_info );
{
int lda = matrix_get_column_stride( A );
double * work = util_malloc( sizeof * work );
double * work = (double*)util_malloc( sizeof * work );
int work_size;
/* First call: determine optimal worksize: */
@@ -550,7 +550,7 @@ int matrix_inv( matrix_type * A ) {
if (info == 0) {
work_size = (int) work[0];
work = util_realloc( work , sizeof * work * work_size );
work = (double*)util_realloc( work , sizeof * work * work_size );
dgetri_( &n , matrix_get_data( A ), &lda , ipiv , work , &work_size , &info);
} else
util_abort("%s: dgetri_ returned info:%d \n",__func__ , info);

View File

@@ -139,7 +139,7 @@ static bool __string_contains(const char * string , const char * char_set) {
menu_type * menu_alloc(const char * title , const char * quit_label , const char * quit_keys) {
menu_type * menu = util_malloc(sizeof * menu );
menu_type * menu = (menu_type*)util_malloc(sizeof * menu );
menu->title = util_alloc_sprintf_escape( title , 0 );
menu->quit_keys = util_alloc_string_copy( quit_keys );
@@ -151,7 +151,7 @@ menu_type * menu_alloc(const char * title , const char * quit_label , const char
}
static menu_item_type * menu_item_alloc_empty() {
menu_item_type * item = util_malloc(sizeof * item );
menu_item_type * item = (menu_item_type*)util_malloc(sizeof * item );
item->label = NULL;
item->key_set = NULL;
@@ -335,7 +335,7 @@ static void menu_display(const menu_type * menu) {
int i;
int length = strlen(menu->title);
for (i = 0; i < vector_get_size(menu->items); i++) {
const menu_item_type * item = vector_iget_const( menu->items , i);
const menu_item_type * item = (const menu_item_type*)vector_iget_const( menu->items , i);
if(!item->helptext)
length = util_int_max(length , item->label_length);
if(item->helptext)
@@ -349,7 +349,7 @@ static void menu_display(const menu_type * menu) {
util_fprintf_string(menu->title , length + 6 , center_pad , stdout); printf(" |\n");
__print_line(length + 10 , 1);
for (i=0; i < vector_get_size(menu->items); i++) {
const menu_item_type * item = vector_iget_const( menu->items , i);
const menu_item_type * item = (const menu_item_type*)vector_iget_const( menu->items , i);
if (item->separator)
__print_sep(length + 6);
else if (item->helptext)
@@ -401,7 +401,7 @@ menu_item_type * menu_get_item(const menu_type * menu, char cmd) {
int item_index = 0;
menu_item_type * item = NULL;
while (item_index < vector_get_size(menu->items)) {
menu_item_type * current_item = vector_iget(menu->items , item_index);
menu_item_type * current_item = (menu_item_type*)vector_iget(menu->items , item_index);
if (!current_item->separator || !current_item->helptext) {
if (strchr(current_item->key_set , cmd) != NULL) {
item = current_item;
@@ -434,7 +434,7 @@ void menu_run(const menu_type * menu) {
{
int item_index = 0;
while (1) {
const menu_item_type * item = vector_iget_const(menu->items , item_index);
const menu_item_type * item = (const menu_item_type*)vector_iget_const(menu->items , item_index);
if (!item->separator) {
if(!item->helptext) {
if (strchr(item->key_set , cmd) != NULL) {

View File

@@ -132,7 +132,7 @@ void msg_update_int(msg_type * msg , const char * fmt , int value) {
UTIL_SAFE_CAST_FUNCTION( msg , MSG_TYPE_ID )
msg_type * msg_alloc(const char * prompt, bool debug) {
msg_type * msg = util_malloc(sizeof * msg );
msg_type * msg = (msg_type*)util_malloc(sizeof * msg );
UTIL_TYPE_ID_INIT( msg , MSG_TYPE_ID);
msg->prompt = util_alloc_string_copy(prompt);

View File

@@ -211,7 +211,7 @@ void mzran_get_state(void * __rng , char * state_buffer) {
void * mzran_alloc( void ) {
mzran_type * rng = util_malloc( sizeof * rng );
mzran_type * rng = (mzran_type*) util_malloc( sizeof * rng );
UTIL_TYPE_ID_INIT( rng , MZRAN_TYPE_ID );
mzran_set_default_state( rng );
return rng;

View File

@@ -53,7 +53,7 @@ struct node_data_struct {
*/
static node_data_type * node_data_alloc__(const void * data , node_ctype ctype , int buffer_size , copyc_ftype * copyc, free_ftype * del) {
node_data_type * node = util_malloc(sizeof * node );
node_data_type * node = (node_data_type*)util_malloc(sizeof * node );
node->ctype = ctype;
node->copyc = copyc;
node->del = del;
@@ -87,27 +87,27 @@ node_data_type * node_data_alloc_buffer(const void * data, int buffer_size) { /
static node_data_type * node_data_copyc(const node_data_type * src , bool deep_copy) {
node_data_type * new;
node_data_type * next;
if (src->buffer_size > 0) {
/*
The source node has internal storage - it has been allocated with _alloc_buffer()
*/
if (deep_copy)
new = node_data_alloc__(util_alloc_copy( src->data , src->buffer_size ) /* A new copy is allocated prior to insert. */
next = node_data_alloc__(util_alloc_copy( src->data , src->buffer_size ) /* A next copy is allocated prior to insert. */
, src->ctype , src->buffer_size , NULL , free);
else
new = node_data_alloc__(src->data , src->ctype , src->buffer_size , NULL , NULL); /* The copy does not have destructor. */
next = node_data_alloc__(src->data , src->ctype , src->buffer_size , NULL , NULL); /* The copy does not have destructor. */
} else {
if (deep_copy) {
if (src->copyc == NULL)
util_abort("%s: Tried allocate deep_copy of mnode with no constructor - aborting. \n",__func__);
new = node_data_alloc__(src->data , src->ctype , 0 , src->copyc , src->del);
next = node_data_alloc__(src->data , src->ctype , 0 , src->copyc , src->del);
} else
new = node_data_alloc__(src->data , src->ctype , 0 , NULL , NULL); /*shallow copy - we 'hide' constructor and destructor. */
next = node_data_alloc__(src->data , src->ctype , 0 , NULL , NULL); /*shallow copy - we 'hide' constructor and destructor. */
}
return new;
return next;
}
node_data_type * node_data_alloc_copy(const node_data_type * node , bool deep_copy) {

View File

@@ -88,7 +88,7 @@ basic_parser_type * basic_parser_alloc(
const char * comment_start, /** Set to NULL if not interessting. */
const char * comment_end) /** Set to NULL if not interessting. */
{
basic_parser_type * parser = util_malloc(sizeof * parser);
basic_parser_type * parser = (basic_parser_type*)util_malloc(sizeof * parser);
parser->splitters = NULL;
parser->delete_set = NULL;
parser->quoters = NULL;
@@ -261,11 +261,11 @@ static int length_of_comment( const char * buffer_position, const basic_parser_
static char * alloc_quoted_token( const char * buffer, int length, bool strip_quote_marks) {
char * token;
if(!strip_quote_marks) {
token = util_calloc( (length + 1) , sizeof * token );
token = (char*)util_calloc( (length + 1) , sizeof * token );
memmove(token, &buffer[0], length * sizeof * token );
token[length] = '\0';
} else {
token = util_calloc( (length - 1) , sizeof * token);
token = (char*)util_calloc( (length - 1) , sizeof * token);
memmove(token, &buffer[1], (length -1) * sizeof * token);
token[length-2] = '\0';
/**
@@ -432,7 +432,7 @@ stringlist_type * basic_parser_tokenize_buffer(
{
int length = length_of_normal_non_splitters( &buffer[position], parser );
char * token = util_calloc( (length + 1) , sizeof * token);
char * token = (char*)util_calloc( (length + 1) , sizeof * token);
int token_length;
if (parser->delete_set == NULL) {
token_length = length;
@@ -623,7 +623,7 @@ bool basic_parser_fseek_string(const basic_parser_type * parser , FILE * stream
void basic_parser_strip_buffer(const basic_parser_type * parser , char ** __buffer) {
char * src = *__buffer;
char * target = util_calloc( ( strlen( *__buffer ) + 1) , sizeof * target );
char * target = (char*)util_calloc( ( strlen( *__buffer ) + 1) , sizeof * target );
int src_position = 0;
int target_position = 0;
@@ -672,7 +672,7 @@ void basic_parser_strip_buffer(const basic_parser_type * parser , char ** __buff
target_position += 1;
}
target[target_position] = '\0';
target = util_realloc( target , sizeof * target * (target_position + 1) );
target = (char*)util_realloc( target , sizeof * target * (target_position + 1) );
free( src );
*__buffer = target;

View File

@@ -76,7 +76,7 @@ void path_fmt_reset_fmt(path_fmt_type * path , const char * fmt) {
static path_fmt_type * path_fmt_alloc__(const char * fmt , bool is_directory) {
path_fmt_type * path = util_malloc(sizeof * path );
path_fmt_type * path = (path_fmt_type*)util_malloc(sizeof * path );
UTIL_TYPE_ID_INIT(path , PATH_FMT_ID);
path->fmt = NULL;
path->file_fmt = NULL;

View File

@@ -51,7 +51,7 @@ struct path_stack_struct {
*/
path_stack_type * path_stack_alloc() {
path_stack_type * path_stack = util_malloc( sizeof * path_stack );
path_stack_type * path_stack = (path_stack_type*)util_malloc( sizeof * path_stack );
path_stack->stack = stringlist_alloc_new();
path_stack->storage = stringlist_alloc_new();
return path_stack;

View File

@@ -36,7 +36,7 @@ struct perm_vector_struct {
*/
perm_vector_type * perm_vector_alloc( int * perm_input, int size ) {
perm_vector_type * perm = util_malloc( sizeof * perm );
perm_vector_type * perm = (perm_vector_type*)util_malloc( sizeof * perm );
UTIL_TYPE_ID_INIT( perm , PERM_VECTOR_TYPE_ID );
perm->size = size;
perm->perm = perm_input;

View File

@@ -38,7 +38,7 @@ static UTIL_SAFE_CAST_FUNCTION( set , SET_TYPE_ID )
set_type * set_alloc(int size, const char ** keyList) {
set_type * set = malloc(sizeof * set);
set_type * set = (set_type*) malloc(sizeof * set);
UTIL_TYPE_ID_INIT( set , SET_TYPE_ID );
set->key_hash = hash_alloc_unlocked();
{
@@ -242,7 +242,7 @@ struct set_iter_struct
set_iter_type * set_iter_alloc(const set_type * set)
{
set_iter_type * set_iter = util_malloc(sizeof * set_iter);
set_iter_type * set_iter = (set_iter_type*) util_malloc(sizeof * set_iter);
set_iter->hash_iter = hash_iter_alloc(set->key_hash);
return set_iter;
}

View File

@@ -153,7 +153,7 @@ static double stepwise_test_var( stepwise_type * stepwise , int test_var , int b
/*True Cross-Validation: */
int * randperms = util_calloc( nsample , sizeof * randperms );
int * randperms = (int*)util_calloc( nsample , sizeof * randperms );
for (int i=0; i < nsample; i++)
randperms[i] = i;
@@ -310,7 +310,7 @@ double stepwise_eval( const stepwise_type * stepwise , const matrix_type * x ) {
static stepwise_type * stepwise_alloc__( int nsample , int nvar , rng_type * rng) {
stepwise_type * stepwise = util_malloc( sizeof * stepwise );
stepwise_type * stepwise = (stepwise_type*)util_malloc( sizeof * stepwise );
stepwise->X_mean = NULL;
stepwise->X_norm = NULL;
@@ -327,7 +327,7 @@ static stepwise_type * stepwise_alloc__( int nsample , int nvar , rng_type * rng
stepwise_type * stepwise_alloc0( rng_type * rng) {
stepwise_type * stepwise = util_malloc( sizeof * stepwise );
stepwise_type * stepwise = (stepwise_type*)util_malloc( sizeof * stepwise );
stepwise->rng = rng;
stepwise->X0 = NULL;

View File

@@ -134,7 +134,7 @@ void stringlist_insert_owned_ref(stringlist_type * stringlist , int index , cons
static stringlist_type * stringlist_alloc_empty( bool alloc_vector ) {
stringlist_type * stringlist = util_malloc(sizeof * stringlist );
stringlist_type * stringlist = (stringlist_type*)util_malloc(sizeof * stringlist );
UTIL_TYPE_ID_INIT( stringlist , STRINGLIST_TYPE_ID);
if (alloc_vector)
@@ -333,20 +333,20 @@ void stringlist_idel(stringlist_type * stringlist , int index) {
char * stringlist_pop( stringlist_type * stringlist) {
return vector_pop_back( stringlist->strings );
return (char*)vector_pop_back( stringlist->strings );
}
const char * stringlist_iget(const stringlist_type * stringlist , int index) {
return vector_iget(stringlist->strings ,index);
return (const char*)vector_iget(stringlist->strings ,index);
}
const char * stringlist_front(const stringlist_type * stringlist) {
return vector_iget(stringlist->strings , 0);
return (const char*)vector_iget(stringlist->strings , 0);
}
const char * stringlist_back(const stringlist_type * stringlist) {
return vector_iget(stringlist->strings , vector_get_size( stringlist->strings ) - 1);
return (const char*)vector_iget(stringlist->strings , vector_get_size( stringlist->strings ) - 1);
}
@@ -395,7 +395,7 @@ bool stringlist_iget_as_bool( const stringlist_type * stringlist, int index, boo
}
const char * stringlist_get_last( const stringlist_type * stringlist ) {
return vector_get_last( stringlist->strings );
return (const char*)vector_get_last( stringlist->strings );
}
@@ -438,7 +438,7 @@ static char ** stringlist_alloc_char__(const stringlist_type * stringlist, bool
int size = stringlist_get_size( stringlist );
if (size > 0) {
int i;
strings = util_calloc(size , sizeof * strings );
strings = (char**)util_calloc(size , sizeof * strings );
for (i = 0; i <size; i++) {
if (deep_copy)
strings[i] = stringlist_iget_copy( stringlist , i);
@@ -572,7 +572,7 @@ char * stringlist_alloc_joined_substring( const stringlist_type * s , int start_
total_length += (strlen(stringlist_iget( s , i)) + sep_length);
total_length += (1 - sep_length);
string = util_malloc( total_length * sizeof * string );
string = (char*)util_malloc( total_length * sizeof * string );
string[0] = '\0';
}
@@ -730,7 +730,7 @@ int stringlist_select_matching(stringlist_type * names , const char * pattern) {
{
int i;
glob_t * pglob = util_malloc( sizeof * pglob );
glob_t * pglob = (glob_t*)util_malloc( sizeof * pglob );
int glob_flags = 0;
glob( pattern , glob_flags , NULL , pglob);
match_count = pglob->gl_pathc;

View File

@@ -38,7 +38,7 @@ UTIL_IS_INSTANCE_FUNCTION( struct_vector , STRUCT_VECTOR_TYPE_ID)
static void struct_vector_resize( struct_vector_type * struct_vector , int new_alloc_size) {
struct_vector->data = util_realloc( struct_vector->data , struct_vector->element_size * new_alloc_size );
struct_vector->data = (char*)util_realloc( struct_vector->data , struct_vector->element_size * new_alloc_size );
struct_vector->alloc_size = new_alloc_size;
}
@@ -57,7 +57,7 @@ struct_vector_type * struct_vector_alloc( int element_size ) {
}
{
struct_vector_type * vector = util_malloc( sizeof * vector );
struct_vector_type * vector = (struct_vector_type*)util_malloc( sizeof * vector );
UTIL_TYPE_ID_INIT( vector , STRUCT_VECTOR_TYPE_ID );
vector->size = 0;
vector->alloc_size = 0;

View File

@@ -67,7 +67,7 @@ char * subst_func_eval( const subst_func_type * subst_func , const stringlist_ty
subst_func_type * subst_func_alloc( const char * func_name , const char * doc_string , subst_func_ftype * func , bool vararg, int argc_min , int argc_max , void * arg) {
subst_func_type * subst_func = util_malloc( sizeof * subst_func );
subst_func_type * subst_func = (subst_func_type*)util_malloc( sizeof * subst_func );
UTIL_TYPE_ID_INIT( subst_func , SUBST_FUNC_TYPE_ID );
subst_func->func = func;
subst_func->name = util_alloc_string_copy( func_name );
@@ -101,7 +101,7 @@ static void subst_func_free__( void * arg ) {
UTIL_IS_INSTANCE_FUNCTION( subst_func_pool , SUBST_FUNC_POOL_TYPE_ID);
subst_func_pool_type * subst_func_pool_alloc( ) {
subst_func_pool_type * pool = util_malloc( sizeof * pool );
subst_func_pool_type * pool = (subst_func_pool_type*)util_malloc( sizeof * pool );
UTIL_TYPE_ID_INIT( pool , SUBST_FUNC_POOL_TYPE_ID );
pool->func_table = hash_alloc_unlocked();
return pool;
@@ -122,7 +122,7 @@ void subst_func_pool_add_func( subst_func_pool_type * pool , const char * func_n
subst_func_type * subst_func_pool_get_func( const subst_func_pool_type * pool , const char * func_name ) {
return hash_get( pool->func_table , func_name );
return (subst_func_type*)hash_get( pool->func_table , func_name );
}
bool subst_func_pool_has_func( const subst_func_pool_type * pool , const char * func_name ) {

View File

@@ -1,940 +0,0 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'subst_list.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.
*/
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <ert/util/util.h>
#include <ert/util/hash.h>
#include <ert/util/vector.h>
#include <ert/util/node_data.h>
#include <ert/util/buffer.h>
#include <ert/util/subst_list.h>
#include <ert/util/subst_func.h>
#include <ert/util/parser.h>
/**
This file implements a small support struct for search-replace
operations, along with wrapped calls to util_string_replace_inplace().
Substitutions can be carried out on files and string in memory (char *
with \0 termination); and the operations can be carried out inplace, or
in a filtering mode where a new file/string is created.
Usage
=====
1. Start with allocating a subst_list instance with subst_list_alloc().
2. Insert key,value pairs to for search-replace with the functions
* subst_list_insert_ref(subst_list , key , value);
* subst_list_insert_owned_ref(subst_list , key , value);
* subst_list_insert_copy(subst_list , key , value );
The difference between these functions is who is owning the memory
pointed to by the value pointer.
3. Do the actual search-replace operation on a file or memory buffer:
* subst_list_filter_file() : Does search-replace on a file.
* subst_list_update_string() : Does search-replace on a buffer.
4. Free the subst_list and go home.
Internally the (key,value) pairs used for substitutions are stored in a
vector, preserving insert order. If you insert the cascade
("A","B")
("B","C")
.....
("Y","Z")
You will eventually end up with a string where all capital letters have
been transformed to 'Z'.
*/
typedef enum { SUBST_DEEP_COPY = 1,
SUBST_MANAGED_REF = 2,
SUBST_SHARED_REF = 3} subst_insert_type; /* Mode used in the subst_list_insert__() function */
#define SUBST_LIST_TYPE_ID 6614320
struct subst_list_struct {
UTIL_TYPE_ID_DECLARATION;
const subst_list_type * parent; /* A parent subst_list instance - can be NULL - no destructor is called for the parent. */
vector_type * string_data; /* The string substitutions we should do. */
vector_type * func_data; /* The functions we support. */
const subst_func_pool_type * func_pool; /* NOT owned by the subst_list instance - can be NULL */
hash_type * map;
};
typedef struct {
subst_func_type * func; /* Pointer to the real subst_func_type - implemented in subst_func.c */
char * name; /* The name the function is recognized as - in this substitution context. */
} subst_list_func_type;
/*
The subst_list type is implemented as a hash of subst_list_node
instances. This node type is not exported out of this file scope at
all.
*/
typedef struct {
bool value_owner; /* Wether the memory pointed to by value should bee freed.*/
char * value;
char * key;
char * doc_string; /* A doc_string of this substitution - only for documentation - can be NULL. */
} subst_list_string_type;
/*****************************************************************/
/* Here comes functions implementing the small
subst_list_string_type */
/** Allocates an empty instance with no values. */
static subst_list_string_type * subst_list_string_alloc(const char * key) {
subst_list_string_type * node = util_malloc(sizeof * node );
node->value_owner = false;
node->value = NULL;
node->doc_string = NULL;
node->key = util_alloc_string_copy( key );
return node;
}
static void subst_list_string_free_content( subst_list_string_type * node ) {
if (node->value_owner)
util_safe_free( node->value );
}
static void subst_list_string_free(subst_list_string_type * node) {
subst_list_string_free_content( node );
util_safe_free( node->doc_string );
free(node->key);
free(node);
}
static void subst_list_string_free__(void * node) {
subst_list_string_free( (subst_list_string_type *) node );
}
/**
input_value can be NULL.
*/
static void subst_list_string_set_value(subst_list_string_type * node, const char * input_value , const char * doc_string , subst_insert_type insert_mode) {
subst_list_string_free_content( node );
{
char * value;
if (insert_mode == SUBST_DEEP_COPY)
value = util_alloc_string_copy(input_value);
else
value = (char *) input_value;
if (insert_mode == SUBST_SHARED_REF)
node->value_owner = false;
else
node->value_owner = true;
node->value = value;
}
if (doc_string != NULL)
node->doc_string = util_realloc_string_copy( node->doc_string , doc_string );
}
/*****************************************************************/
/**
When arriving at this function the main subst scope should already have verified that
the requested function is available in the function pool.
*/
static subst_list_func_type * subst_list_func_alloc( const char * func_name, subst_func_type * func) {
subst_list_func_type * subst_func = util_malloc( sizeof * subst_func );
subst_func->name = util_alloc_string_copy( func_name );
subst_func->func = func;
return subst_func;
}
static void subst_list_func_free( subst_list_func_type * subst_func ) {
free( subst_func->name );
free( subst_func );
}
static void subst_list_func_free__(void * node) {
subst_list_func_free( (subst_list_func_type *) node );
}
static char * subst_list_func_eval( const subst_list_func_type * subst_func , const stringlist_type * arglist) {
return subst_func_eval(subst_func->func , arglist );
}
/*****************************************************************/
/**
Find the node corresponding to 'key' - returning NULL if it is not found.
*/
static subst_list_string_type * subst_list_get_string_node(const subst_list_type * subst_list , const char * key) {
subst_list_string_type * node = NULL;
int index = 0;
/* Linear search ... */ /*Should use map*/
while ((index < vector_get_size(subst_list->string_data)) && (node == NULL)) {
subst_list_string_type * inode = vector_iget( subst_list->string_data , index);
if (strcmp(inode->key , key) == 0) /* Found it */
node = inode;
else
index++;
}
return node;
}
static subst_list_string_type * subst_list_insert_new_node(subst_list_type * subst_list , const char * key , bool append) {
subst_list_string_type * new_node = subst_list_string_alloc(key);
if (append)
vector_append_owned_ref( subst_list->string_data , new_node , subst_list_string_free__ );
else
vector_insert_owned_ref( subst_list->string_data , 0 , new_node , subst_list_string_free__ );
hash_insert_ref( subst_list->map , key , new_node );
return new_node;
}
/*****************************************************************/
UTIL_IS_INSTANCE_FUNCTION( subst_list , SUBST_LIST_TYPE_ID )
/**
Observe that this function sets both the subst parent, and the pool
of available functions. If this is call is repeated it is possible
to create a weird config with dangling function pointers - that is
a somewhat contrived and pathological use case, and not checked
for.
*/
void subst_list_set_parent( subst_list_type * subst_list , const subst_list_type * parent) {
subst_list->parent = parent;
if (parent != NULL)
subst_list->func_pool = subst_list->parent->func_pool;
}
const subst_list_type * subst_list_get_parent( const subst_list_type * subst_list ) {
return subst_list->parent;
}
bool subst_list_has_key( const subst_list_type * subst_list , const char * key) {
return hash_has_key( subst_list->map , key );
}
/*
The input argument is currently only (void *), runtime it will be
checked whether it is of type subst_list_type, in which case it is
interpreted as a parent instance, if it is of type
subst_func_pool_type it is interpreted as a func_pool instance,
otherwise the function will fail hard.
If the the input argument is a subst_list parent, the func_pool of
the parent is used also for the newly allocated subst_list
instance.
*/
subst_list_type * subst_list_alloc(const void * input_arg) {
subst_list_type * subst_list = util_malloc(sizeof * subst_list );
UTIL_TYPE_ID_INIT( subst_list , SUBST_LIST_TYPE_ID);
subst_list->parent = NULL;
subst_list->func_pool = NULL;
subst_list->map = hash_alloc();
subst_list->string_data = vector_alloc_new();
subst_list->func_data = vector_alloc_new();
if (input_arg != NULL) {
if (subst_list_is_instance( input_arg ))
subst_list_set_parent( subst_list , input_arg );
else if (subst_func_pool_is_instance( input_arg ))
subst_list->func_pool = input_arg;
else
util_abort("%s: run_time cast failed - invalid type on input argument.\n",__func__);
}
return subst_list;
}
/**
The semantics of the doc_string string is as follows:
1. If doc_string is different from NULL the doc_string is stored in the node.
2. If a NULL value follows a non-NULL value (i.e. the substitution
is updated) the doc_string is not changed.
The idea is that the doc_string must just be included the first
time a (key,value) pair is added. On subsequent updates of the
value, the doc_string string can be NULL.
*/
static void subst_list_insert__(subst_list_type * subst_list , const char * key , const char * value , const char * doc_string, bool append ,
subst_insert_type insert_mode) {
subst_list_string_type * node = subst_list_get_string_node(subst_list , key);
if (node == NULL) /* Did not have the node. */
node = subst_list_insert_new_node(subst_list , key ,append);
subst_list_string_set_value(node , value , doc_string , insert_mode);
}
/**
There are three different functions for inserting a key-value pair
in the subst_list instance. The difference between the three is in
which scope takes/has ownership of 'value'. The alternatives are:
subst_list_insert_ref: In this case the calling scope has full
ownership of value, and is consquently responsible for freeing
it, and ensuring that it stays a valid pointer for the subst_list
instance. Probably the most natural function to use when used
with static storage, i.e. typically string literals.
subst_list_insert_owned_ref: In this case the subst_list takes
ownership of the value reference, in the sense that it will
free it when it is done.
subst_list_insert_copy: In this case the subst_list takes a copy
of value and inserts it. Meaning that the substs_list instance
takes repsonibility of freeing, _AND_ the calling scope is free
to do whatever it wants with the value pointer.
*/
void subst_list_append_ref(subst_list_type * subst_list , const char * key , const char * value, const char * doc_string) {
subst_list_insert__(subst_list , key , value , doc_string , true , SUBST_SHARED_REF);
}
void subst_list_append_owned_ref(subst_list_type * subst_list , const char * key , const char * value, const char * doc_string) {
subst_list_insert__(subst_list , key , value , doc_string , true , SUBST_MANAGED_REF);
}
void subst_list_append_copy(subst_list_type * subst_list , const char * key , const char * value, const char * doc_string) {
subst_list_insert__(subst_list , key , value , doc_string , true , SUBST_DEEP_COPY);
}
void subst_list_prepend_ref(subst_list_type * subst_list , const char * key , const char * value, const char * doc_string) {
subst_list_insert__(subst_list , key , value , doc_string , false , SUBST_SHARED_REF);
}
void subst_list_prepend_owned_ref(subst_list_type * subst_list , const char * key , const char * value, const char * doc_string) {
subst_list_insert__(subst_list , key , value , doc_string , false , SUBST_MANAGED_REF);
}
void subst_list_prepend_copy(subst_list_type * subst_list , const char * key , const char * value, const char * doc_string) {
subst_list_insert__(subst_list , key , value , doc_string , false , SUBST_DEEP_COPY);
}
/**
This function will install the function @func_name from the current
subst_func_pool, it will be made available to this subst_list
instance with the function name @local_func_name. If @func_name is
not available, the function will fail hard.
*/
void subst_list_insert_func(subst_list_type * subst_list , const char * func_name , const char * local_func_name) {
if (subst_list->func_pool != NULL && subst_func_pool_has_func( subst_list->func_pool , func_name )) {
subst_list_func_type * subst_func = subst_list_func_alloc( local_func_name , subst_func_pool_get_func( subst_list->func_pool , func_name ));
vector_append_owned_ref( subst_list->func_data , subst_func , subst_list_func_free__ );
} else
util_abort("%s: function:%s not available \n",__func__ , func_name);
}
void subst_list_clear( subst_list_type * subst_list ) {
vector_clear( subst_list->string_data );
}
void subst_list_free(subst_list_type * subst_list) {
vector_free( subst_list->string_data );
vector_free( subst_list->func_data );
hash_free( subst_list->map );
free(subst_list);
}
/*****************************************************************/
/*
Below comes many different functions for doing the actual updating
the functions differ in the form of the input and output. At the
lowest level, is the function
subst_list_uppdate_buffer()
which will update a buffer instance. This function again will call
two separate functions for pure string substitutions and for
function evaluation.
The update replace functions will first apply all the string
substitutions for this particular instance, and afterwards calling
all the string substititions of the parent (recursively); the same
applies to the function replacements.
*/
/*****************************************************************/
/**
Updates the buffer inplace with all the string substitutions in the
subst_list. This is the lowest level function, which does *NOT*
consider the parent pointer.
*/
static bool subst_list_replace_strings__(const subst_list_type * subst_list , buffer_type * buffer) {
int index;
bool global_match = false;
for (index = 0; index < vector_get_size( subst_list->string_data ); index++) {
const subst_list_string_type * node = vector_iget_const( subst_list->string_data , index );
if (node->value != NULL) {
bool match;
buffer_rewind( buffer );
do {
match = buffer_search_replace( buffer , node->key , node->value);
if (match)
global_match = true;
} while (match);
}
}
return global_match;
}
/**
Updates the buffer inplace by evaluationg all the string functions
in the subst_list. Last performing all the replacements in the
parent.
The rules for function evaluation are as follows:
1. Every function MUST have a '()', IMMEDIATELY following the
function name, this also applies to functions which do not have
any arguments.
2. The function parser is quite primitive, and can (at least
currently) not handle nested functions, i.e.
__SUM__( __SUM__(1 ,2 ) , 3)
will fail.
3. If the function evaluation fails; typicall because of wrong
type/number of arguments the buffer will not updated.
4. The functions will return a freshly allocated (char *) pointer,
or NULL if the evaluation fails, and the input value is a list
of strings extracted from the parsing context - i.e. the
function is in no way limited to numeric functions like sum()
and exp().
*/
static bool subst_list_eval_funcs____(const subst_list_type * subst_list , const basic_parser_type * parser , buffer_type * buffer) {
bool global_match = false;
int index;
for (index = 0; index < vector_get_size( subst_list->func_data); index++) {
const subst_list_func_type * subst_func = vector_iget_const( subst_list->func_data , index );
const char * func_name = subst_func->name;
bool match;
buffer_rewind( buffer );
do {
size_t match_pos;
match = buffer_strstr( buffer , func_name );
match_pos = buffer_get_offset( buffer );
if (match) {
bool update = false;
char * arg_start = buffer_get_data( buffer );
arg_start += buffer_get_offset( buffer ) + strlen( func_name );
if (arg_start[0] == '(') { /* We require that an opening paren follows immediately behind the function name. */
char * arg_end = strchr( arg_start , ')');
if (arg_end != NULL) {
/* OK - we found an enclosing () pair. */
char * arg_content = util_alloc_substring_copy( arg_start, 1 , arg_end - arg_start - 1);
stringlist_type * arg_list = basic_parser_tokenize_buffer( parser , arg_content , true);
char * func_eval = subst_list_func_eval( subst_func , arg_list );
int old_len = strlen(func_name) + strlen( arg_content) + 2;
if (func_eval != NULL) {
buffer_memshift( buffer , match_pos + old_len , strlen( func_eval ) - old_len);
buffer_fwrite( buffer , func_eval , strlen( func_eval ) , sizeof * func_eval );
free( func_eval );
update = true;
global_match = true;
}
free( arg_content );
stringlist_free( arg_list );
}
}
if (!update)
buffer_fseek( buffer , match_pos + strlen( func_name ) , SEEK_SET);
}
} while (match);
}
if (subst_list->parent != NULL)
global_match = (subst_list_eval_funcs____( subst_list->parent , parser , buffer ) || global_match);
return global_match;
}
static bool subst_list_eval_funcs__(const subst_list_type * subst_list , buffer_type * buffer) {
basic_parser_type * parser = basic_parser_alloc( "," , "\"\'" , NULL , " \t" , NULL , NULL );
bool match = subst_list_eval_funcs____( subst_list , parser , buffer );
basic_parser_free( parser );
return match;
}
/**
Should we evaluate the parent first (i.e. top down), or this
instance first and then subsequently the parent (i.e. bottom
up). The problem is with inherited defintions:
Inherited defintions
--------------------
In this situation we have defined a (key,value) substitution,
where the value depends on a value following afterwards:
("<PATH>" , "/tmp/run/<CASE>")
("<CASE>" , "Test4")
I.e. first <PATH> is replaced with "/tmp/run/<CASE>" and then
subsequently "<CASE>" is replaced with "Test4". A typical use
case here is that the common definition of "<PATH>" is in the
parent, and consequently parent should run first (i.e. top
down).
However, in other cases the order of defintion might very well be
opposite, i.e. with "<CASE>" first and then things will blow up:
1. <CASE>: Not found
2. <PATH> -> /tmp/run/<CASE>
and, the final <CASE> will not be resolved. I.e. there is no
obvious 'right' way to do it.
Overriding defaults
-------------------
The parent has defined:
("<PATH>" , "/tmp/run/default")
But for a particular instance we would like to overwrite <PATH>
with another definition:
("<PATH>" , "/tmp/run/special_case")
This will require evaluating the bottom first, i.e. a bottom up
approach.
Currently the implementation is purely top down, the latter case
above is not supported. The actual implementation here is in terms
of recursion, the low level function doing the stuff is
subst_list_replace_strings__() which is not recursive.
*/
static bool subst_list_replace_strings( const subst_list_type * subst_list , buffer_type * buffer ) {
bool match = false;
if (subst_list->parent != NULL)
match = subst_list_replace_strings( subst_list->parent , buffer );
/* The actual string replace */
match = (subst_list_replace_strings__( subst_list , buffer ) || match);
return match;
}
/*
This function updates a buffer instance inplace with all the
substitutions in the subst_list.
This is the common low-level function employed by all the the
subst_update_xxx() functions. Observe that it is a hard assumption
that the buffer has a \0 terminated string.
*/
bool subst_list_update_buffer( const subst_list_type * subst_list , buffer_type * buffer ) {
bool match1 = subst_list_replace_strings( subst_list , buffer );
bool match2 = subst_list_eval_funcs__( subst_list , buffer );
return (match1 || match2); // Funny construction to ensure to avoid fault short circuit.
}
/**
This function reads the content of a file, and writes a new file
where all substitutions in subst_list have been performed. Observe
that target_file and src_file *CAN* point to the same file, in
which case this will amount to an inplace update. In that case a
backup file is written, and held, during the execution of the
function.
Observe that @target_file can contain a path component, that
component will be created if it does not exist.
*/
bool subst_list_filter_file(const subst_list_type * subst_list , const char * src_file , const char * target_file) {
bool match;
char * backup_file = NULL;
buffer_type * buffer = buffer_fread_alloc( src_file );
buffer_fseek( buffer , 0 , SEEK_END ); /* Ensure that the buffer is a \0 terminated string. */
buffer_fwrite_char( buffer , '\0');
/*****************************************************************/
/* Backup file ?? */
if (util_same_file(src_file , target_file)) {
char * backup_prefix = util_alloc_sprintf("%s-%s" , src_file , __func__);
backup_file = util_alloc_tmp_file("/tmp" , backup_prefix , false);
free(backup_prefix);
}
/* Writing backup file */
if (backup_file != NULL) {
FILE * stream = util_fopen(backup_file , "w");
buffer_stream_fwrite_n( buffer , 0 , -1 , stream ); /* -1: Do not write the trailing \0. */
fclose(stream);
}
/* Doing the actual update */
match = subst_list_update_buffer(subst_list , buffer);
/* Writing updated file */
{
FILE * stream = util_mkdir_fopen(target_file , "w");
buffer_stream_fwrite_n( buffer , 0 , -1 , stream ); /* -1: Do not write the trailing \0. */
fclose(stream);
}
/* OK - all went hunka dory - unlink the backup file and leave the building. */
if (backup_file != NULL) {
remove( backup_file );
free( backup_file );
}
buffer_free( buffer );
return match;
}
/**
This function does search-replace on a file inplace.
*/
bool subst_list_update_file(const subst_list_type * subst_list , const char * file) {
return subst_list_filter_file( subst_list , file , file );
}
/**
This function does search-replace on string instance inplace.
*/
bool subst_list_update_string(const subst_list_type * subst_list , char ** string) {
buffer_type * buffer = buffer_alloc_private_wrapper( *string , strlen( *string ) + 1);
bool match = subst_list_update_buffer(subst_list , buffer);
*string = buffer_get_data( buffer );
buffer_free_container( buffer );
return match;
}
/**
This function allocates a new string where the search-replace
operation has been performed.
*/
char * subst_list_alloc_filtered_string(const subst_list_type * subst_list , const char * string) {
char * filtered_string = util_alloc_string_copy( string );
subst_list_update_string( subst_list , &filtered_string );
return filtered_string;
}
/**
This function writes a filtered version of string to a file.
*/
void subst_list_filtered_fprintf(const subst_list_type * subst_list , const char * string , FILE * stream) {
buffer_type * buffer = buffer_alloc( strlen(string) + 1 );
buffer_fwrite( buffer , string , 1 , strlen( string ) + 1);
subst_list_update_buffer(subst_list , buffer);
buffer_stream_fwrite_n( buffer , 0 , -1 , stream ); /* -1: The trailing \0 is not explicitly written to file. */
buffer_free(buffer);
}
/**
This function will perform subst-based substitution on all the
elements in the stringlist. The stringlist is modified in place,
and the following applies to memory:
o Elements inserted with _ref() are just dropped on the floor,
they were the responsability of the calling scope anyway.
o Elements inserted with _owned_ref() are freed - INVALIDATING A
POSSIBLE POINTER IN THE CALLING SCOPE.
o The newly inserted element is inserted as _owned_ref() -
i.e. with a destructor.
*/
void stringlist_apply_subst(stringlist_type * stringlist , const subst_list_type * subst_list) {
int i;
for (i=0; i < stringlist_get_size( stringlist ); i++) {
const char * old_string = stringlist_iget( stringlist , i );
char * new_string = subst_list_alloc_filtered_string( subst_list , old_string );
stringlist_iset_owned_ref( stringlist , i , new_string );
}
}
/*****************************************************************/
/* End of update/apply functions */
/*****************************************************************/
/**
This allocates a new subst_list instance, the copy process is deep,
in the sense that all srings inserted in the new subst_list
instance have their own storage, irrespective of the ownership in
the original subst_list instance.
*/
subst_list_type * subst_list_alloc_deep_copy(const subst_list_type * src) {
subst_list_type * copy;
if (src->parent != NULL)
copy = subst_list_alloc( src->parent );
else
copy = subst_list_alloc( src->func_pool);
{
int index;
for (index = 0; index < vector_get_size( src->string_data ); index++) {
const subst_list_string_type * node = vector_iget_const( src->string_data , index );
subst_list_insert__( copy , node->key , node->value , node->doc_string , true , SUBST_DEEP_COPY);
}
for (index = 0; index < vector_get_size( src->func_data ); index++) {
const subst_list_func_type * src_node = vector_iget_const( src->func_data , index );
subst_list_func_type * copy_node = subst_list_func_alloc( src_node->name , src_node->func );
vector_append_owned_ref( copy->func_data , copy_node , subst_list_func_free__ );
}
}
return copy;
}
int subst_list_get_size( const subst_list_type * subst_list) {
return vector_get_size(subst_list->string_data);
}
const char * subst_list_iget_key( const subst_list_type * subst_list , int index) {
if (index < vector_get_size(subst_list->string_data)) {
const subst_list_string_type * node = vector_iget_const( subst_list->string_data , index );
return node->key;
} else {
util_abort("%s: index:%d to large \n",__func__ , index);
return NULL;
}
}
const char * subst_list_iget_value( const subst_list_type * subst_list , int index) {
if (index < vector_get_size(subst_list->string_data)) {
const subst_list_string_type * node = vector_iget_const( subst_list->string_data , index );
return node->value;
} else {
util_abort("%s: index:%d to large \n",__func__ , index);
return NULL;
}
}
const char * subst_list_get_value( const subst_list_type * subst_list , const char * key) {
const subst_list_string_type * node = hash_get( subst_list->map , key );
return node->value;
}
const char * subst_list_iget_doc_string( const subst_list_type * subst_list , int index) {
if (index < vector_get_size(subst_list->string_data)) {
const subst_list_string_type * node = vector_iget_const( subst_list->string_data , index );
return node->doc_string;
} else {
util_abort("%s: index:%d to large \n",__func__ , index);
return NULL;
}
}
void subst_list_fprintf(const subst_list_type * subst_list , FILE * stream) {
int index;
for (index=0; index < vector_get_size( subst_list->string_data ); index++) {
const subst_list_string_type * node = vector_iget_const( subst_list->string_data , index );
fprintf(stream , "%s = %s\n" , node->key , node->value);
}
}
/**
Will allocate string representation of the subst_list as:
KEY1=Value1, Key2=Value2, Key3=Value3. Will return NULL is there
are no elements in the subst_list.
*/
char * subst_list_alloc_string_representation( const subst_list_type * subst_list ) {
int size = subst_list_get_size( subst_list );
char * return_string = NULL;
if (size > 0) {
buffer_type * buffer = buffer_alloc( 512 );
int i;
for (i=0; i < size; i++) {
buffer_fwrite_char_ptr( buffer , subst_list_iget_key( subst_list , i));
buffer_strcat(buffer , "=");
buffer_strcat( buffer , subst_list_iget_value( subst_list , i));
if (i < (size - 1))
buffer_strcat( buffer , ", ");
}
buffer_shrink_to_fit( buffer );
return_string = buffer_get_data( buffer );
buffer_free_container( buffer );
}
return return_string;
}
/** Will loose tagging .... */
int subst_list_add_from_string( subst_list_type * subst_list , const char * arg_string, bool append) {
int error_count = 0;
if (arg_string != NULL) {
char ** key_value_list;
int num_arg, iarg;
util_split_string(arg_string , "," , &num_arg , &key_value_list);
for (iarg = 0; iarg < num_arg; iarg++) {
if (strchr(key_value_list[iarg] , '=') == NULL)
//util_abort("%s: could not find \'=\' in argument string:%s \n",__func__ , key_value_list[iarg]);
/*
Could not find '=' in the argument string, this argument will
be ignored, and the error_count will be increased by one.
*/
error_count += 1;
else {
char * key , * value;
char * tmp = key_value_list[iarg];
int arg_length , value_length;
while (isspace(*tmp)) /* Skipping initial space */
tmp++;
arg_length = strcspn(tmp , " =");
key = util_alloc_substring_copy(tmp , 0 , arg_length);
tmp += arg_length;
while ((*tmp == ' ') || (*tmp == '='))
tmp++;
value_length = strcspn(tmp , " ");
value = util_alloc_substring_copy( tmp , 0 , value_length);
/* Setting the argument */
if (append)
subst_list_append_copy( subst_list , key , value , NULL);
else
subst_list_prepend_copy( subst_list , key , value , NULL);
free(key);
free(value);
tmp += value_length;
/* Accept only trailing space - any other character indicates a failed parsing. */
while (*tmp != '\0') {
if (!isspace(*tmp))
util_abort("%s: something wrong with:%s - spaces are not allowed in key or value part.\n",__func__ , key_value_list[iarg]);
tmp++;
}
}
}
util_free_stringlist(key_value_list , num_arg);
}
return error_count;
}
/*****************************************************************/

View File

@@ -1,227 +0,0 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'template.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.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <ert/util/ert_api_config.h>
#include <ert/util/util.h>
#include <ert/util/subst_list.h>
#include <ert/util/subst_func.h>
#include <ert/util/template.h>
#include <ert/util/template_type.h>
#include <ert/util/stringlist.h>
/**
Iff the template is set up with internaliz_template == false the
template content is loaded at instantiation time, and in that case
the name of the template file can contain substitution characters -
i.e. in this case different instance can use different source
templates.
To avoid race issues this function does not set actually update the
state of the template object.
*/
static char * template_load( const template_type * template , const subst_list_type * ext_arg_list) {
int buffer_size;
char * template_file = util_alloc_string_copy( template->template_file );
char * template_buffer;
subst_list_update_string( template->arg_list , &template_file);
if (ext_arg_list != NULL)
subst_list_update_string( ext_arg_list , &template_file);
template_buffer = util_fread_alloc_file_content( template_file , &buffer_size );
free( template_file );
return template_buffer;
}
void template_set_template_file( template_type * template , const char * template_file) {
template->template_file = util_realloc_string_copy( template->template_file , template_file );
if (template->internalize_template) {
util_safe_free( template->template_buffer );
template->template_buffer = template_load( template , NULL );
}
}
/** This will not instantiate */
const char * template_get_template_file( const template_type * template ) {
return template->template_file;
}
/**
This function allocates a template object based on the source file
'template_file'. If @internalize_template is true the template
content will be read and internalized at boot time, otherwise that
is deferred to template instantiation time (in which case the
template file can change dynamically).
*/
template_type * template_alloc( const char * template_file , bool internalize_template , subst_list_type * parent_subst) {
template_type * template = util_malloc( sizeof * template );
UTIL_TYPE_ID_INIT(template , TEMPLATE_TYPE_ID);
template->arg_list = subst_list_alloc( parent_subst );
template->template_buffer = NULL;
template->template_file = NULL;
template->internalize_template = internalize_template;
template->arg_string = NULL;
template_set_template_file( template , template_file );
#ifdef ERT_HAVE_REGEXP
template_init_loop_regexp( template );
#endif
return template;
}
void template_free( template_type * template ) {
subst_list_free( template->arg_list );
util_safe_free( template->template_file );
util_safe_free( template->template_buffer );
util_safe_free( template->arg_string );
#ifdef ERT_HAVE_REGEXP
regfree( &template->start_regexp );
regfree( &template->end_regexp );
#endif
free( template );
}
/**
This function will create the file @__target_file based on the
template instance. Before the target file is written all the
internal substitutions and then subsequently the subsititutions in
@arg_list will be performed. The input @arg_list can be NULL - in
which case this is more like copy operation.
Observe that:
1. Substitutions will be performed on @__target_file
2. @__target_file can contain path components.
3. If internalize_template == false subsititions will be performed
on the filename of the file with template content.
4. If the parameter @override_symlink is true the function will
have the following behaviour:
If the target_file already exists as a symbolic link, the
symbolic link will be removed prior to creating the instance,
ensuring that a remote file is not updated.
*/
void template_instantiate( const template_type * template , const char * __target_file , const subst_list_type * arg_list , bool override_symlink) {
char * target_file = util_alloc_string_copy( __target_file );
/* Finding the name of the target file. */
subst_list_update_string( template->arg_list , &target_file);
if (arg_list != NULL) subst_list_update_string( arg_list , &target_file );
{
char * char_buffer;
/* Loading the template - possibly expanding keys in the filename */
if (template->internalize_template)
char_buffer = util_alloc_string_copy( template->template_buffer);
else
char_buffer = template_load( template , arg_list );
/* Substitutions on the content. */
subst_list_update_string( template->arg_list , &char_buffer );
if (arg_list != NULL) subst_list_update_string( arg_list , &char_buffer );
#ifdef ERT_HAVE_REGEXP
{
buffer_type * buffer = buffer_alloc_private_wrapper( char_buffer , strlen( char_buffer ) + 1);
template_eval_loops( template , buffer );
char_buffer = buffer_get_data( buffer );
buffer_free_container( buffer );
}
#endif
/*
Check if target file already exists as a symlink,
and remove it if override_symlink is true.
*/
if (override_symlink) {
if (util_is_link( target_file ))
remove( target_file );
}
/* Write the content out. */
{
FILE * stream = util_mkdir_fopen( target_file , "w");
fprintf(stream , "%s" , char_buffer);
fclose( stream );
}
free( char_buffer );
}
free( target_file );
}
/**
Add an internal key_value pair. This substitution will be performed
before the internal substitutions.
*/
void template_add_arg( template_type * template , const char * key , const char * value ) {
subst_list_append_copy( template->arg_list , key , value , NULL /* No doc_string */);
}
void template_clear_args( template_type * template ) {
subst_list_clear( template->arg_list );
}
int template_add_args_from_string( template_type * template , const char * arg_string) {
return subst_list_add_from_string( template->arg_list , arg_string , true);
}
char * template_get_args_as_string( template_type * template ) {
util_safe_free( template->arg_string );
template->arg_string = subst_list_alloc_string_representation( template->arg_list );
return template->arg_string;
}
/*****************************************************************/

View File

@@ -1,292 +0,0 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'template_loop.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.
*/
#include <ert/util/ert_api_config.h>
#include <ctype.h>
#include <sys/types.h>
#include <regex.h>
#include <ert/util/parser.h>
#include <ert/util/stringlist.h>
#include <ert/util/template.h>
#include <ert/util/template_type.h>
#define END_REGEXP "[{]%[[:space:]]+endfor[[:space:]]+%[}]"
#define LOOP_REGEXP "[{]%[[:space:]]+for[[:space:]]+([$]?[[:alpha:]][[:alnum:]]*)[[:space:]]+in[[:space:]]+[[]([^]]*)[]][[:space:]]+%[}]"
#define LOOP_OPTIONS REG_EXTENDED
#define END_OPTIONS REG_EXTENDED
#define DOLLAR '$'
/*
This file implements a simple looping construct in the templates. The support
is strongly based on the POSIX regexp functionality; and this file will not
be compiled unless that support is present.
*/
struct loop_struct {
int opentag_offset;
int opentag_length;
int endtag_offset;
int endtag_length;
int body_offset;
int body_length;
bool replace_substring;
int var_length;
char * loop_var;
stringlist_type * items;
};
static void regcompile(regex_t * reg , const char * reg_string , int flags) {
int error = regcomp(reg , reg_string , flags);
if (error) {
int error_size = 256;
char error_buffer[256];
regerror(error , reg , error_buffer , error_size);
util_exit("Compile of %s failed: %s \n",LOOP_REGEXP, error_buffer);
}
}
static loop_type * loop_alloc( const char * buffer , int global_offset , regmatch_t tag_offset , regmatch_t __var_offset , regmatch_t __items_offset) {
loop_type * loop = util_malloc( sizeof * loop);
loop->opentag_offset = global_offset + tag_offset.rm_so;
loop->opentag_length = tag_offset.rm_eo - tag_offset.rm_so;
loop->endtag_offset = -1;
loop->endtag_length = -1;
loop->body_offset = loop->opentag_offset + loop->opentag_length;
loop->body_length = -1;
{
int var_offset = global_offset + __var_offset.rm_so;
int var_length = __var_offset.rm_eo - __var_offset.rm_so;
loop->loop_var = util_alloc_substring_copy( buffer , var_offset , var_length );
loop->var_length = strlen( loop->loop_var );
if (loop->loop_var[0] == DOLLAR)
loop->replace_substring = true;
else
loop->replace_substring = false;
}
{
int items_offset = global_offset + __items_offset.rm_so;
int items_length = __items_offset.rm_eo - __items_offset.rm_so;
char * items_string = util_alloc_substring_copy( buffer , items_offset , items_length );
basic_parser_type * parser = basic_parser_alloc("," , NULL , NULL , NULL , NULL , NULL); // Does not tolerate spaces around the splitting ","
loop->items = basic_parser_tokenize_buffer( parser , items_string , false);
basic_parser_free( parser );
free( items_string );
}
return loop;
}
static void loop_set_endmatch( loop_type * loop , int global_offset , regmatch_t end_offset) {
loop->endtag_offset = global_offset + end_offset.rm_so;
loop->endtag_length = end_offset.rm_eo - end_offset.rm_so;
loop->body_length = loop->endtag_offset - loop->opentag_offset - loop->opentag_length;
}
static void loop_free( loop_type * loop ) {
free( loop->loop_var );
stringlist_free( loop->items );
free( loop );
}
static void replace_1var( buffer_type * var_expansion , int shift , int write_offset , int shift_offset , const char * value) {
buffer_memshift( var_expansion , shift_offset , shift );
buffer_fseek( var_expansion , write_offset , SEEK_SET );
buffer_fwrite( var_expansion , value , strlen(value) , 1);
}
static void loop_eval( const loop_type * loop , const char * body , buffer_type * var_expansion , int ivar) {
buffer_clear( var_expansion );
buffer_fwrite_char_ptr( var_expansion , body );
{
const char * value = stringlist_iget( loop->items , ivar );
int value_length = strlen( value );
int shift = value_length - loop->var_length;
int search_offset = 0;
while (true) {
char * data = buffer_get_data( var_expansion );
char * match_ptr = strstr( &data[search_offset] , loop->loop_var );
if (match_ptr == NULL)
break;
else {
/* Check that the match is either at the very start of the
string, or alternatively NOT preceeded by alphanumeric
character. If the variable starts with a '$' we ignore this
test.
*/
if (!loop->replace_substring) {
if (match_ptr != &data[search_offset]) { char
pre_char = match_ptr[-1]; if (isalnum( pre_char )) {
search_offset = match_ptr - data + 1;
if (search_offset >= strlen(data))
break;
else
continue;
}
}
/*
Check that the match is at the very end of the string, or
alternatively followed by a NON alphanumeric character. */
if (strlen(match_ptr) > loop->var_length) {
char end_char = match_ptr[ loop->var_length ];
if (isalnum( end_char ))
break;
}
}
/* OK - this is a valid match; update the string buffer. */
{
int write_offset = match_ptr - data;
int shift_offset = write_offset + loop->var_length;
replace_1var( var_expansion , shift , write_offset , shift_offset , value );
search_offset = write_offset + loop->var_length;
}
}
}
}
}
int template_eval_loop( const template_type * template , buffer_type * buffer , int global_offset , loop_type * loop) {
int flags = 0;
int NMATCH = 3;
regmatch_t match_list_loop[NMATCH];
regmatch_t match_list_end[NMATCH];
int search_offset = loop->opentag_offset + loop->opentag_length;
{
int end_match , loop_match;
{
char * search_data = buffer_get_data( buffer ); // This pointer must be refetched because the buffer can realloc and move it.
loop_match = regexec( &template->start_regexp , &search_data[search_offset] , NMATCH , match_list_loop , flags );
end_match = regexec( &template->end_regexp , &search_data[search_offset] , NMATCH , match_list_end , flags );
}
if (end_match == REG_NOMATCH)
return -1; // This for loop does not have a matching {% endfor %}
if (loop_match == 0) {
if (match_list_loop[0].rm_so < match_list_end[0].rm_so) {
// This is a nested sub loop - evaluate that recursively.
char * search_data = buffer_get_data( buffer );
loop_type * sub_loop = loop_alloc( search_data , search_offset , match_list_loop[0] , match_list_loop[1] , match_list_loop[2]);
global_offset = template_eval_loop( template , buffer , global_offset , sub_loop );
}
}
/*****************************************************************/
/* We have completed the sub loops; the buffer has (possibly)
changed so we must search for the end again - to get the right
offset. */
{
char * search_data = buffer_get_data( buffer );
search_offset = global_offset;
end_match = regexec( &template->end_regexp , &search_data[search_offset] , NMATCH , match_list_end , flags );
if (end_match == REG_NOMATCH)
util_exit("Fatal error - have lost a {% endfor %} marker \n");
}
/* This loop is the inner loop - expand it. */
loop_set_endmatch( loop , search_offset , match_list_end[0]);
{
buffer_type * loop_expansion = buffer_alloc( loop->body_length * stringlist_get_size( loop->items) );
{
char * src_data = buffer_get_data( buffer );
char * body = util_alloc_substring_copy( src_data , loop->body_offset , loop->body_length );
buffer_type * var_expansion = buffer_alloc( 0 );
int ivar;
for (ivar =0; ivar < stringlist_get_size( loop->items ); ivar++) {
loop_eval(loop , body , var_expansion , ivar );
buffer_strcat( loop_expansion , buffer_get_data( var_expansion ));
}
buffer_free( var_expansion );
util_safe_free( body );
}
{
int tag_length = loop->endtag_offset + loop->endtag_length - loop->opentag_offset;
int offset = loop->endtag_offset + loop->endtag_length;
int shift = buffer_get_string_size( loop_expansion ) - tag_length;
buffer_memshift( buffer , offset , shift );
buffer_fseek( buffer , loop->opentag_offset , SEEK_SET );
buffer_fwrite( buffer , buffer_get_data( loop_expansion ) , 1 , buffer_get_string_size( loop_expansion ));
global_offset = loop->opentag_offset + buffer_get_string_size( loop_expansion );
}
buffer_free( loop_expansion );
}
loop_free( loop );
}
return global_offset;
}
void template_init_loop_regexp( template_type * template ) {
regcompile( &template->start_regexp , LOOP_REGEXP , LOOP_OPTIONS );
regcompile( &template->end_regexp , END_REGEXP , END_OPTIONS );
}
void template_eval_loops( const template_type * template , buffer_type * buffer ) {
int NMATCH = 10;
regmatch_t match_list[NMATCH];
{
int global_offset = 0;
while( true ) {
char * src_data = buffer_get_data( buffer );
int match = regexec(&template->start_regexp , &src_data[global_offset] , NMATCH , match_list , 0);
if (match == 0) {
loop_type * loop = loop_alloc( src_data , global_offset , match_list[0] , match_list[1] , match_list[2]);
global_offset = template_eval_loop( template , buffer , global_offset , loop );
if (global_offset < 0) {
fprintf(stderr,"** Warning ** : found {%% for .... %%} loop construct without mathcing {%% endfor %%}\n");
break;
}
} else if (match == REG_NOMATCH)
break;
}
}
}

View File

@@ -37,7 +37,7 @@ void test_error_exit( const char * fmt , ...) {
va_start(ap , fmt);
s = util_alloc_sprintf_va(fmt , ap);
va_end(ap);
fprintf(stderr , s );
fprintf(stderr, "%s", s);
exit(1);
}
@@ -50,7 +50,7 @@ void test_exit__(const char * file , int line , const char * fmt , ...) {
va_start(ap , fmt);
s = util_alloc_sprintf_va(fmt , ap);
va_end(ap);
fprintf(stderr , s );
fprintf(stderr, "%s", s);
exit(1);
}
}

View File

@@ -131,7 +131,7 @@ static test_work_area_type * test_work_area_alloc__(const char * prefix , const
char * test_cwd = util_alloc_sprintf(FULL_PATH_FMT , prefix , test_path );
util_make_path( test_cwd );
if (true) {
work_area = util_malloc( sizeof * work_area );
work_area = (test_work_area_type*)util_malloc( sizeof * work_area );
UTIL_TYPE_ID_INIT( work_area , TEST_WORK_AREA_TYPE_ID );
work_area->original_cwd = util_alloc_cwd();

View File

@@ -1,109 +0,0 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'ert_util_block_fs.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.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <sys/types.h>
#include <unistd.h>
#include <ert/util/block_fs.h>
#include <ert/util/test_util.h>
#include <ert/util/test_work_area.h>
void test_assert_util_abort(const char * function_name , void call_func (void *) , void * arg);
void violating_fwrite( void * arg ) {
block_fs_type * bfs = block_fs_safe_cast( arg );
block_fs_fwrite_file( bfs , "name" , NULL , 100 );
}
void test_readonly( ) {
test_work_area_type * work_area = test_work_area_alloc("block_fs/read_only");
block_fs_type * bfs = block_fs_mount( "test.mnt" , 1000 , 10000 , 0.67 , 10 , true , true , false );
test_assert_true( block_fs_is_readonly( bfs ));
test_assert_util_abort("block_fs_aquire_wlock" , violating_fwrite , bfs );
block_fs_close(bfs , true);
test_work_area_free( work_area );
}
void createFS1() {
pid_t pid = fork();
if (pid == 0) {
block_fs_type * bfs = block_fs_mount( "test.mnt" , 1000 , 10000 , 0.67 , 10 , true , false , true );
test_assert_false( block_fs_is_readonly( bfs ) );
test_assert_true( util_file_exists("test.lock_0"));
{
int total_sleep = 0;
while (true) {
if (util_file_exists( "stop")) {
unlink("stop");
break;
}
usleep(1000);
total_sleep += 1000;
if (total_sleep > 1000000 * 5) {
fprintf(stderr,"Test failure - never receieved \"stop\" file from parent process \n");
break;
}
}
}
block_fs_close( bfs , false );
exit(0);
}
usleep(10000);
}
void test_lock_conflict() {
test_work_area_type * work_area = test_work_area_alloc("block_fs/lock_conflict");
createFS1();
while (true) {
if (util_file_exists("test.lock_0"))
break;
}
{
block_fs_type * bfs = block_fs_mount( "test.mnt" , 1000 , 10000 , 0.67 , 10 , true , false , true );
test_assert_true( block_fs_is_readonly( bfs ) );
}
{
FILE * stream = util_fopen("stop" , "w");
fclose( stream );
}
while (util_file_exists( "stop")) {
usleep( 1000 );
}
test_work_area_free( work_area );
}
int main(int argc , char ** argv) {
test_readonly();
test_lock_conflict();
exit(0);
}

View File

@@ -16,6 +16,10 @@
for more details.
*/
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
@@ -25,8 +29,208 @@
void test_sscanf_bool() {
char const* expected_true = "1\0___""T\0___""True\0""tRuE";
int const expected_true_step = 5;
char const* const expected_true_end = expected_true + 4 * expected_true_step;
void test_sscan_percent() {
char const* expected_false = "0\0____""F\0____""False\0""fALse";
int const expected_false_step = 6;
char const* const expected_false_end = expected_false + 4 * expected_false_step;
char const* expected_fail = "\0___""t\0___""f\0___""Tru\0""asd";
int const expected_fail_step = 4;
char const* const expected_fail_end = expected_fail + 5 * expected_fail_step;
bool value = false;
for(; expected_true < expected_true_end; expected_true += expected_true_step) {
value = false;
test_assert_true( util_sscanf_bool( expected_true, &value) );
test_assert_bool_equal(value, true);
}
for(; expected_false < expected_false_end; expected_false += expected_false_step) {
value = true;
test_assert_true( util_sscanf_bool( expected_false, &value) );
test_assert_bool_equal(value, false);
}
for(; expected_fail < expected_fail_end; expected_fail += expected_fail_step) {
value = true;
test_assert_false( util_sscanf_bool( expected_fail, &value) );
test_assert_bool_equal(value, false);
}
// Test null buffer
value = true;
test_assert_false( util_sscanf_bool(NULL, &value) );
test_assert_bool_equal(value, false);
test_assert_false( util_sscanf_bool(NULL, NULL) );
}
void test_sscanf_bytesize() {
size_t value = 0u;
test_assert_true(util_sscanf_bytesize("1KB", &value));
test_assert_size_t_equal(value, 1024);
test_assert_true(util_sscanf_bytesize("12 mB", &value));
test_assert_size_t_equal(value, 12 * 1024 * 1024);
test_assert_true(util_sscanf_bytesize("-47", &value));
test_assert_size_t_equal(value, (size_t )(-47)); // documentation says overflows are not checked for
value = 0u;
test_assert_false(util_sscanf_bytesize("3.7 MB", &value)); // no decimals allowed
test_assert_size_t_equal(value, 0u);
test_assert_false(util_sscanf_bytesize("14 TB", &value)); // TB not supported yet
test_assert_size_t_equal(value, 0u);
// Test NULL buffer
test_assert_false(util_sscanf_bytesize(NULL, &value));
test_assert_size_t_equal(value, 0); // documentation says the value is set to 0 on parsing error
test_assert_false(util_sscanf_bytesize(NULL, NULL));
}
void test_sscanf_double() {
double value = 1.0;
test_assert_true( util_sscanf_double("0.0", &value) );
test_assert_double_equal(value, 0.0);
test_assert_true(util_sscanf_double("47.35", &value));
test_assert_double_equal(value, 47.35);
test_assert_true( util_sscanf_double("-0.0", &value) );
test_assert_double_equal(value, 0.0);
test_assert_true(util_sscanf_double("-54.1341", &value));
test_assert_double_equal(value, -54.1341);
test_assert_true(util_sscanf_double("-.1341", &value));
test_assert_double_equal(value, -0.1341);
test_assert_true(util_sscanf_double("+.284", &value));
test_assert_double_equal(value, 0.284);
test_assert_true(util_sscanf_double("-.45e-2", &value));
test_assert_double_equal(value, -0.0045);
test_assert_true(util_sscanf_double("0xFF", &value));
test_assert_double_equal(value, 255);
test_assert_true(util_sscanf_double("INF", &value));
test_assert_double_equal(value, INFINITY);
test_assert_true(util_sscanf_double("NaN", &value));
test_assert_true(isnan(value));
// double max and min
char buffer[30];
snprintf(buffer, 30, "-%.20g", DBL_MAX);
test_assert_true(util_sscanf_double(buffer, &value));
test_assert_double_equal(value, -DBL_MAX);
snprintf(buffer, 30, "%.20g", DBL_MIN);
test_assert_true(util_sscanf_double(buffer, &value));
test_assert_double_equal(value, DBL_MIN);
// Garbage characters
value = 15.3;
test_assert_false(util_sscanf_double("0x12GWS", &value));
test_assert_double_equal(value, 15.3);
test_assert_false(util_sscanf_double("--.+", &value));
test_assert_double_equal(value, 15.3);
// NULL buffer
value = 15.3;
test_assert_false( util_sscanf_double(NULL, &value) );
test_assert_double_equal(value, 15.3);
test_assert_false( util_sscanf_double(NULL, NULL) );
}
void test_sscanf_int() {
int value = 1;
test_assert_true( util_sscanf_int("0", &value) );
test_assert_int_equal(value, 0);
test_assert_true( util_sscanf_int("241", &value) );
test_assert_int_equal(value, 241);
test_assert_true( util_sscanf_int("-0", &value) );
test_assert_int_equal(value, 0);
test_assert_true( util_sscanf_int("-852", &value) );
test_assert_int_equal(value, -852);
value = 1;
test_assert_false( util_sscanf_int("+-+-+-", &value) );
test_assert_int_equal(value, 1);
test_assert_false( util_sscanf_int("7.5", &value) );
test_assert_int_equal(value, 1);
// max and min
char buffer[30];
snprintf(buffer, 30, "-%d", INT_MAX);
test_assert_true(util_sscanf_int(buffer, &value));
test_assert_int_equal(value, -INT_MAX);
snprintf(buffer, 30, "%d", INT_MIN);
test_assert_true(util_sscanf_int(buffer, &value));
test_assert_int_equal(value, INT_MIN);
// NULL buffer
value = 9;
test_assert_false( util_sscanf_int(NULL, &value) );
test_assert_int_equal(value, 9);
test_assert_false( util_sscanf_int(NULL, NULL) );
}
void test_sscanf_octal_int() {
int value = 1;
test_assert_true(util_sscanf_octal_int("0", &value));
test_assert_int_equal(value, 0);
test_assert_true(util_sscanf_octal_int("241", &value));
test_assert_int_equal(value, 2 * 64 + 4 * 8 + 1);
test_assert_true(util_sscanf_octal_int("-0", &value));
test_assert_int_equal(value, 0);
test_assert_true(util_sscanf_octal_int("-1742", &value));
test_assert_int_equal(value, -(512 + 7 * 64 + 4 * 8 + 2));
value = 1;
test_assert_false(util_sscanf_octal_int("--5++", &value));
test_assert_int_equal(value, 1);
test_assert_false(util_sscanf_octal_int("89", &value));
test_assert_int_equal(value, 1);
test_assert_false(util_sscanf_octal_int("7.5", &value));
test_assert_int_equal(value, 1);
// NULL buffer
value = 3;
test_assert_false(util_sscanf_octal_int(NULL, &value));
test_assert_int_equal(value, 3);
test_assert_false(util_sscanf_octal_int(NULL, NULL));
}
void test_sscanf_percent() {
{
const char * MIN_REALIZATIONS = "10%";
double value = 0.0;
@@ -62,10 +266,20 @@ void test_sscan_percent() {
test_assert_double_equal(0.0, value);
}
{
double value = 12.5;
test_assert_false(util_sscanf_percent(NULL, &value));
test_assert_double_equal(12.5, value);
}
{
test_assert_false(util_sscanf_percent(NULL, NULL));
}
}
void test_date(time_t expected , const char * date_string, bool expected_return) {
void check_iso_date(time_t expected , const char * date_string, bool expected_return) {
time_t t;
bool valid = util_sscanf_isodate(date_string, &t);
@@ -77,9 +291,9 @@ void test_date(time_t expected , const char * date_string, bool expected_return)
}
void test_scan_iso_date() {
void test_sscanf_isodate() {
time_t expected = util_make_date_utc(10, 11 , 2011);
test_date( expected , "2011-11-10", true);
check_iso_date( expected , "2011-11-10", true);
test_assert_false( util_sscanf_isodate( "2017.10.07" , NULL ));
test_assert_false( util_sscanf_isodate( "2017-10.7" , NULL ));
@@ -88,12 +302,36 @@ void test_scan_iso_date() {
/* Invalid numeric values */
test_assert_false( util_sscanf_isodate( "2017-15-07" , NULL ));
test_assert_false( util_sscanf_isodate( "2017-10-47" , NULL ));
// Test NULL buffer
check_iso_date( expected , NULL, false);
test_assert_false(util_sscanf_isodate(NULL, NULL));
}
void test_sscanf_date_utc() {
time_t value = 0;
test_assert_true(util_sscanf_date_utc("16.07^1997", &value));
test_assert_time_t_equal(value, util_make_date_utc(16, 7, 1997));
value = util_make_date_utc(10, 11, 2011);
test_assert_false(util_sscanf_date_utc(NULL, &value));
test_assert_time_t_equal(value, -1);
test_assert_false(util_sscanf_date_utc(NULL, NULL));
}
int main(int argc , char ** argv) {
test_sscan_percent();
test_scan_iso_date();
test_sscanf_bool();
test_sscanf_bytesize();
test_sscanf_date_utc();
test_sscanf_double();
test_sscanf_int();
test_sscanf_isodate();
test_sscanf_octal_int();
test_sscanf_percent();
exit(0);
}

View File

@@ -1,97 +0,0 @@
/*
Copyright (C) 2015 Statoil ASA, Norway.
The file 'ert_util_subst_list.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.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <ert/util/test_work_area.h>
#include <ert/util/subst_list.h>
#include <ert/util/test_util.h>
void test_create() {
subst_list_type * subst_list = subst_list_alloc( NULL );
test_assert_true( subst_list_is_instance( subst_list ) );
subst_list_free( subst_list );
}
void test_filter_file1() {
subst_list_type * subst_list = subst_list_alloc( NULL );
test_work_area_type * work_area = test_work_area_alloc("subst_list/filter1");
{
FILE * stream = util_fopen("template" , "w");
fprintf(stream , "<KEY1>\n<KEY2>\n<KEY3>\n<KEY4>\n");
fclose(stream);
}
subst_list_append_copy( subst_list , "<KEY1>" , "Value1" , NULL);
subst_list_append_copy( subst_list , "<KEY2>" , "Value2" , NULL);
subst_list_append_copy( subst_list , "<KEY3>" , "Value3" , NULL);
subst_list_append_copy( subst_list , "<KEY4>" , "Value4" , NULL);
subst_list_filter_file( subst_list , "template" , "target");
{
FILE * stream = util_fopen("target" , "r");
char s1[128],s2[128],s3[128],s4[128];
test_assert_int_equal( 4 , fscanf( stream , "%s %s %s %s" , s1,s2,s3,s4));
fclose(stream);
test_assert_string_equal( s1 , "Value1");
test_assert_string_equal( s2 , "Value2");
test_assert_string_equal( s3 , "Value3");
test_assert_string_equal( s4 , "Value4");
}
test_work_area_free( work_area );
subst_list_free( subst_list );
}
void test_filter_file2() {
subst_list_type * subst_list = subst_list_alloc( NULL );
test_work_area_type * work_area = test_work_area_alloc("subst_list/filter2");
{
FILE * stream = util_fopen("template" , "w");
fprintf(stream , "MAGIC_PRINT magic-list.txt <ERTCASE> __MAGIC__");
fclose(stream);
}
subst_list_append_copy( subst_list , "<QC_PATH>" , "QC" , NULL);
subst_list_append_copy( subst_list , "__MAGIC__" , "MagicAllTheWayToWorkFlow" , NULL);
subst_list_append_copy( subst_list , "<CASE>" , "SUPERcase" , NULL);
subst_list_append_copy( subst_list , "<ERTCASE>" , "default" , NULL);
subst_list_filter_file( subst_list , "template" , "target");
{
char * target_string = util_fread_alloc_file_content( "target" , NULL );
test_assert_string_equal( target_string , "MAGIC_PRINT magic-list.txt default MagicAllTheWayToWorkFlow");
free( target_string );
}
test_work_area_free( work_area );
subst_list_free( subst_list );
}
int main(int argc , char ** argv) {
test_create();
test_filter_file1();
test_filter_file2();
}

View File

@@ -107,8 +107,17 @@ void test_sort() {
test_assert_string_equal( "3" , vector_iget(v2 , 3 ));
test_assert_string_equal( "4" , vector_iget(v2 , 4 ));
vector_permute( v1 , sort_map );
test_assert_string_equal( "0" , vector_iget(v1 , 0 ));
test_assert_string_equal( "1" , vector_iget(v1 , 1 ));
test_assert_string_equal( "2" , vector_iget(v1 , 2 ));
test_assert_string_equal( "3" , vector_iget(v1 , 3 ));
test_assert_string_equal( "4" , vector_iget(v1 , 4 ));
int_vector_free( sort_map );
}
vector_free( v1 );
vector_free( v2 );
}
void test_find( ) {

View File

@@ -153,7 +153,7 @@ static UTIL_SAFE_CAST_FUNCTION( thread_pool , THREAD_POOL_TYPE_ID )
static void thread_pool_resize_queue( thread_pool_type * pool, int queue_length ) {
pthread_rwlock_wrlock( &pool->queue_lock );
{
pool->queue = util_realloc( pool->queue , queue_length * sizeof * pool->queue );
pool->queue = (thread_pool_arg_type*)util_realloc( pool->queue , queue_length * sizeof * pool->queue );
pool->queue_alloc_size = queue_length;
}
pthread_rwlock_unlock( &pool->queue_lock );
@@ -242,7 +242,7 @@ static void * thread_pool_main_loop( void * arg ) {
take a copy of the node we are interested in.
*/
pthread_rwlock_rdlock( &tp->queue_lock );
tp_arg = util_alloc_copy( &tp->queue[ tp->queue_index ] , sizeof * tp_arg );
tp_arg = (thread_pool_arg_type*)util_alloc_copy( &tp->queue[ tp->queue_index ] , sizeof * tp_arg );
pthread_rwlock_unlock( &tp->queue_lock );
tp_arg->slot_index = slot_index;
@@ -366,15 +366,15 @@ bool thread_pool_try_join(thread_pool_type * pool, int timeout_seconds) {
pool->join = true; /* Signals to the main thread that joining can start. */
if (pool->max_running > 0) {
struct timespec ts;
time_t timeout_time = time( NULL );
util_inplace_forward_seconds_utc(&timeout_time , timeout_seconds );
ts.tv_sec = timeout_time;
ts.tv_nsec = 0;
#ifdef HAVE_TIMEDJOIN
struct timespec ts;
ts.tv_sec = timeout_time;
ts.tv_nsec = 0;
{
int join_return = pthread_timedjoin_np( pool->dispatch_thread , NULL , &ts); /* Wait for the main thread to complete. */
if (join_return == 0)
@@ -423,9 +423,9 @@ bool thread_pool_try_join(thread_pool_type * pool, int timeout_seconds) {
*/
thread_pool_type * thread_pool_alloc(int max_running , bool start_queue) {
thread_pool_type * pool = util_malloc( sizeof *pool );
thread_pool_type * pool = (thread_pool_type*)util_malloc( sizeof *pool );
UTIL_TYPE_ID_INIT( pool , THREAD_POOL_TYPE_ID );
pool->job_slots = util_calloc( max_running , sizeof * pool->job_slots );
pool->job_slots = (thread_pool_job_slot_type*)util_calloc( max_running , sizeof * pool->job_slots );
pool->max_running = max_running;
pool->queue = NULL;
pool->accepting_jobs = false;

Some files were not shown because too many files have changed in this diff Show More