2013-01-18 09:00:23 +01:00
/*
2015-10-30 09:43:10 +01:00
Copyright ( C ) 2011 Statoil ASA , Norway .
The file ' stringlist . 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 .
2013-01-18 09:00:23 +01:00
*/
# include <string.h>
# include <stdio.h>
# include <stdlib.h>
2016-04-19 14:48:14 +02:00
# include <ert/util/ert_api_config.h>
# ifdef ERT_HAVE_GLOB
2013-01-18 09:00:23 +01:00
# include <glob.h>
# else
# include <Windows.h>
# endif
2013-01-31 15:39:40 +01:00
# include <ert/util/util.h>
# include <ert/util/stringlist.h>
# include <ert/util/vector.h>
# include <ert/util/buffer.h>
2013-01-18 09:00:23 +01:00
# define STRINGLIST_TYPE_ID 671855
/**
This file implements a very thin wrapper around a list ( vector ) of
strings , and the total number of strings . It is mostly to avoid
sending both argc and argv .
2015-10-30 09:43:10 +01:00
2013-01-18 09:00:23 +01:00
Most of the functionality is implemented through vector . c and
stateless functions in util . c
*/
# ifdef __cplusplus
extern " C " {
# endif
struct stringlist_struct {
UTIL_TYPE_ID_DECLARATION ;
vector_type * strings ;
} ;
static void stringlist_fprintf__ ( const stringlist_type * stringlist , const char * sep , FILE * stream ) {
int length = vector_get_size ( stringlist - > strings ) ;
2013-04-04 08:24:40 +02:00
if ( length > 0 ) {
int i ;
for ( i = 0 ; i < length - 1 ; i + + ) {
const char * s = stringlist_iget ( stringlist , i ) ;
fprintf ( stream , " %s%s " , s , sep ) ;
}
2015-10-30 09:43:10 +01:00
2013-04-04 08:24:40 +02:00
fprintf ( stream , " %s " , stringlist_iget ( stringlist , length - 1 ) ) ;
2013-01-18 09:00:23 +01:00
}
}
void stringlist_fprintf ( const stringlist_type * stringlist , const char * sep , FILE * stream ) {
stringlist_fprintf__ ( stringlist , sep , stream ) ;
}
void stringlist_fprintf_fmt ( const stringlist_type * stringlist , const stringlist_type * fmt_list , FILE * stream ) {
if ( stringlist_get_size ( stringlist ) = = stringlist_get_size ( fmt_list ) ) {
int i ;
for ( i = 0 ; i < stringlist_get_size ( stringlist ) ; i + + )
fprintf ( stream , stringlist_iget ( fmt_list , i ) , stringlist_iget ( stringlist , i ) ) ;
} util_abort ( " %s: length of stringlist:%d length of fmt_list:%d - must be equal \n " , __func__ , stringlist_get_size ( stringlist ) , stringlist_get_size ( fmt_list ) ) ;
}
/**
This function appends a copy of s into the stringlist .
*/
void stringlist_append_copy ( stringlist_type * stringlist , const char * s ) {
vector_append_buffer ( stringlist - > strings , s , strlen ( s ) + 1 ) ;
}
void stringlist_append_ref ( stringlist_type * stringlist , const char * s ) {
vector_append_ref ( stringlist - > strings , s ) ;
}
void stringlist_append_owned_ref ( stringlist_type * stringlist , const char * s ) {
vector_append_owned_ref ( stringlist - > strings , s , free ) ;
}
/*****************************************************************/
void stringlist_iset_copy ( stringlist_type * stringlist , int index , const char * s ) {
vector_iset_buffer ( stringlist - > strings , index , s , strlen ( s ) + 1 ) ;
}
void stringlist_iset_ref ( stringlist_type * stringlist , int index , const char * s ) {
vector_iset_ref ( stringlist - > strings , index , s ) ;
}
void stringlist_iset_owned_ref ( stringlist_type * stringlist , int index , const char * s ) {
vector_iset_owned_ref ( stringlist - > strings , index , s , free ) ;
}
/*****************************************************************/
void stringlist_insert_copy ( stringlist_type * stringlist , int index , const char * s ) {
vector_insert_buffer ( stringlist - > strings , index , s , strlen ( s ) + 1 ) ;
}
void stringlist_insert_ref ( stringlist_type * stringlist , int index , const char * s ) {
vector_insert_ref ( stringlist - > strings , index , s ) ;
}
void stringlist_insert_owned_ref ( stringlist_type * stringlist , int index , const char * s ) {
vector_insert_owned_ref ( stringlist - > strings , index , s , free ) ;
}
static stringlist_type * stringlist_alloc_empty ( bool alloc_vector ) {
2017-08-29 07:48:38 +02:00
stringlist_type * stringlist = ( stringlist_type * ) util_malloc ( sizeof * stringlist ) ;
2013-01-18 09:00:23 +01:00
UTIL_TYPE_ID_INIT ( stringlist , STRINGLIST_TYPE_ID ) ;
if ( alloc_vector )
stringlist - > strings = vector_alloc_new ( ) ;
else
stringlist - > strings = NULL ;
2015-10-30 09:43:10 +01:00
2013-01-18 09:00:23 +01:00
return stringlist ;
}
stringlist_type * stringlist_alloc_new ( ) {
return stringlist_alloc_empty ( true ) ;
}
stringlist_type * stringlist_alloc_argv_copy ( const char * * argv , int argc ) {
int iarg ;
stringlist_type * stringlist = stringlist_alloc_empty ( true ) ;
2015-10-30 09:43:10 +01:00
for ( iarg = 0 ; iarg < argc ; iarg + + )
2013-01-18 09:00:23 +01:00
stringlist_append_copy ( stringlist , argv [ iarg ] ) ;
2015-10-30 09:43:10 +01:00
2013-01-18 09:00:23 +01:00
return stringlist ;
}
stringlist_type * stringlist_alloc_argv_ref ( const char * * argv , int argc ) {
int iarg ;
stringlist_type * stringlist = stringlist_alloc_empty ( true ) ;
2015-10-30 09:43:10 +01:00
for ( iarg = 0 ; iarg < argc ; iarg + + )
2013-01-18 09:00:23 +01:00
stringlist_append_ref ( stringlist , argv [ iarg ] ) ;
return stringlist ;
}
stringlist_type * stringlist_alloc_argv_owned_ref ( const char * * argv , int argc ) {
int iarg ;
stringlist_type * stringlist = stringlist_alloc_empty ( true ) ;
2015-10-30 09:43:10 +01:00
for ( iarg = 0 ; iarg < argc ; iarg + + )
2013-01-18 09:00:23 +01:00
stringlist_append_owned_ref ( stringlist , argv [ iarg ] ) ;
2015-10-30 09:43:10 +01:00
2013-01-18 09:00:23 +01:00
return stringlist ;
}
2015-10-30 09:43:10 +01:00
/**
2013-01-18 09:00:23 +01:00
Allocates a new stringlist instance where all the new string are
references to the string found in the existing stringlist
2015-10-30 09:43:10 +01:00
instance .
*/
2013-01-18 09:00:23 +01:00
stringlist_type * stringlist_alloc_shallow_copy ( const stringlist_type * src ) {
stringlist_type * copy = stringlist_alloc_empty ( false ) ;
copy - > strings = vector_alloc_copy ( src - > strings , false ) ;
return copy ;
}
/**
Allocates a new stringlist where the strings are references to the
num_strings found in stringlist from start .
*/
stringlist_type * stringlist_alloc_shallow_copy_with_limits ( const stringlist_type * stringlist , int offset , int num_strings ) {
stringlist_type * copy = stringlist_alloc_empty ( true ) ;
int i ;
for ( i = 0 ; i < num_strings ; i + + )
{
const char * str = stringlist_iget ( stringlist , i + offset ) ;
vector_append_ref ( copy - > strings , str ) ;
}
return copy ;
}
/*
Can not use vector_deep copy - because we might not have the
constructor registered , in the node_data instance ; but in this case
we know the copy constructor .
*/
stringlist_type * stringlist_alloc_deep_copy_with_limits ( const stringlist_type * src , int offset , int num_strings ) {
stringlist_type * copy = stringlist_alloc_empty ( true ) ;
int i ;
2015-10-30 09:43:10 +01:00
for ( i = 0 ; i < num_strings ; i + + )
2013-01-18 09:00:23 +01:00
stringlist_append_copy ( copy , stringlist_iget ( src , i + offset ) ) ;
return copy ;
}
stringlist_type * stringlist_alloc_deep_copy_with_offset ( const stringlist_type * src , int offset ) {
return stringlist_alloc_deep_copy_with_limits ( src , offset , stringlist_get_size ( src ) - offset ) ;
}
stringlist_type * stringlist_alloc_deep_copy ( const stringlist_type * src ) {
return stringlist_alloc_deep_copy_with_offset ( src , 0 ) ;
}
void stringlist_append_stringlist_copy ( stringlist_type * stringlist , const stringlist_type * src ) {
int i ;
for ( i = 0 ; i < stringlist_get_size ( src ) ; i + + )
stringlist_append_copy ( stringlist , stringlist_iget ( src , i ) ) ;
}
void stringlist_append_stringlist_ref ( stringlist_type * stringlist , const stringlist_type * src ) {
int i ;
for ( i = 0 ; i < stringlist_get_size ( src ) ; i + + )
stringlist_append_ref ( stringlist , stringlist_iget ( src , i ) ) ;
}
/**
Insert a copy of a stringlist in some position .
2015-10-30 09:43:10 +01:00
2013-01-18 09:00:23 +01:00
Can probably be made more efficient .
*/
void stringlist_insert_stringlist_copy ( stringlist_type * stringlist , const stringlist_type * src , int pos ) {
int size_old = stringlist_get_size ( stringlist ) ;
/** Cannot use assert_index here. */
if ( pos < 0 | | pos > size_old )
util_abort ( " %s: Position %d is out of bounds. Min: 0 Max: %d \n " , pos , size_old ) ;
{
stringlist_type * start = stringlist_alloc_new ( ) ;
stringlist_type * end = stringlist_alloc_new ( ) ;
stringlist_type * newList = stringlist_alloc_new ( ) ;
int i ;
for ( i = 0 ; i < pos ; i + + )
stringlist_append_ref ( start , stringlist_iget ( stringlist , i ) ) ;
for ( i = pos ; i < size_old ; i + + )
stringlist_append_ref ( end , stringlist_iget ( stringlist , i ) ) ;
stringlist_append_stringlist_copy ( newList , start ) ;
stringlist_append_stringlist_copy ( newList , src ) ;
stringlist_append_stringlist_copy ( newList , end ) ;
stringlist_clear ( stringlist ) ;
stringlist_append_stringlist_copy ( stringlist , newList ) ;
stringlist_free ( newList ) ;
stringlist_free ( start ) ;
stringlist_free ( end ) ;
}
}
void stringlist_deep_copy ( stringlist_type * target , const stringlist_type * src ) {
stringlist_clear ( target ) ;
{
int i ;
for ( i = 0 ; i < stringlist_get_size ( src ) ; i + + )
stringlist_append_copy ( target , stringlist_iget ( src , i ) ) ;
}
}
2015-10-30 09:43:10 +01:00
/**
2013-01-18 09:00:23 +01:00
Frees all the memory contained by the stringlist .
*/
void stringlist_clear ( stringlist_type * stringlist ) {
vector_clear ( stringlist - > strings ) ;
}
void stringlist_free ( stringlist_type * stringlist ) {
stringlist_clear ( stringlist ) ;
vector_free ( stringlist - > strings ) ;
free ( stringlist ) ;
}
static UTIL_SAFE_CAST_FUNCTION ( stringlist , STRINGLIST_TYPE_ID ) ;
UTIL_IS_INSTANCE_FUNCTION ( stringlist , STRINGLIST_TYPE_ID )
void stringlist_free__ ( void * __stringlist ) {
stringlist_type * stringlist = stringlist_safe_cast ( __stringlist ) ;
stringlist_free ( stringlist ) ;
}
void stringlist_idel ( stringlist_type * stringlist , int index ) {
vector_idel ( stringlist - > strings , index ) ;
}
2013-04-04 08:24:40 +02:00
char * stringlist_pop ( stringlist_type * stringlist ) {
2017-08-29 07:48:38 +02:00
return ( char * ) vector_pop_back ( stringlist - > strings ) ;
2013-04-04 08:24:40 +02:00
}
2013-01-18 09:00:23 +01:00
const char * stringlist_iget ( const stringlist_type * stringlist , int index ) {
2017-08-29 07:48:38 +02:00
return ( const char * ) vector_iget ( stringlist - > strings , index ) ;
2013-01-18 09:00:23 +01:00
}
2013-12-09 15:19:06 +01:00
const char * stringlist_front ( const stringlist_type * stringlist ) {
2017-08-29 07:48:38 +02:00
return ( const char * ) vector_iget ( stringlist - > strings , 0 ) ;
2013-12-09 15:19:06 +01:00
}
const char * stringlist_back ( const stringlist_type * stringlist ) {
2017-08-29 07:48:38 +02:00
return ( const char * ) vector_iget ( stringlist - > strings , vector_get_size ( stringlist - > strings ) - 1 ) ;
2013-12-09 15:19:06 +01:00
}
2013-04-04 08:24:40 +02:00
int stringlist_iget_as_int ( const stringlist_type * stringlist , int index , bool * valid ) {
const char * string_value = stringlist_iget ( stringlist , index ) ;
int value = - 1 ;
2015-10-30 09:43:10 +01:00
2013-04-04 08:24:40 +02:00
if ( valid ! = NULL )
* valid = false ;
2015-10-30 09:43:10 +01:00
if ( util_sscanf_int ( string_value , & value ) )
2013-04-04 08:24:40 +02:00
if ( valid ! = NULL )
* valid = true ;
return value ;
}
2015-04-14 15:47:22 +02:00
double stringlist_iget_as_double ( const stringlist_type * stringlist , int index , bool * valid ) {
const char * string_value = stringlist_iget ( stringlist , index ) ;
double value = - 1.0 ;
if ( valid ! = NULL )
* valid = false ;
if ( util_sscanf_double ( string_value , & value ) )
if ( valid ! = NULL )
* valid = true ;
return value ;
}
2014-10-09 20:13:04 +02:00
bool stringlist_iget_as_bool ( const stringlist_type * stringlist , int index , bool * valid ) {
const char * string_value = stringlist_iget ( stringlist , index ) ;
bool value = false ;
if ( valid ! = NULL )
* valid = false ;
if ( util_sscanf_bool ( string_value , & value ) )
if ( valid ! = NULL )
* valid = true ;
return value ;
}
2013-04-04 08:24:40 +02:00
const char * stringlist_get_last ( const stringlist_type * stringlist ) {
2017-08-29 07:48:38 +02:00
return ( const char * ) vector_get_last ( stringlist - > strings ) ;
2013-04-04 08:24:40 +02:00
}
2013-01-18 09:00:23 +01:00
bool stringlist_iequal ( const stringlist_type * stringlist , int index , const char * s ) {
return util_string_equal ( stringlist_iget ( stringlist , index ) , s ) ;
}
/**
Will return NULL if you ask for something beyond the limits of the
stringlist ( will die on negative index - that is NEVER OK ) .
*/
const char * stringlist_safe_iget ( const stringlist_type * stringlist , int index ) {
if ( index < 0 )
util_abort ( " %s: negative index:%d is NOT allowed \n " , __func__ , index ) ;
if ( index < stringlist_get_size ( stringlist ) )
return stringlist_iget ( stringlist , index ) ;
else
return NULL ;
}
char * stringlist_iget_copy ( const stringlist_type * stringlist , int index ) {
return util_alloc_string_copy ( stringlist_iget ( stringlist , index ) ) ;
}
int stringlist_get_size ( const stringlist_type * stringlist ) {
return vector_get_size ( stringlist - > strings ) ;
}
/*
2015-10-30 09:43:10 +01:00
Return NULL if the list has zero entries .
2013-01-18 09:00:23 +01:00
*/
static char * * stringlist_alloc_char__ ( const stringlist_type * stringlist , bool deep_copy ) {
char * * strings = NULL ;
int size = stringlist_get_size ( stringlist ) ;
if ( size > 0 ) {
int i ;
2017-08-29 07:48:38 +02:00
strings = ( char * * ) util_calloc ( size , sizeof * strings ) ;
2013-01-18 09:00:23 +01:00
for ( i = 0 ; i < size ; i + + ) {
if ( deep_copy )
strings [ i ] = stringlist_iget_copy ( stringlist , i ) ;
else
strings [ i ] = ( char * ) stringlist_iget ( stringlist , i ) ;
}
}
return strings ;
}
char * * stringlist_alloc_char_copy ( const stringlist_type * stringlist ) {
return stringlist_alloc_char__ ( stringlist , true ) ;
}
char * * stringlist_alloc_char_ref ( const stringlist_type * stringlist ) {
return stringlist_alloc_char__ ( stringlist , false ) ;
}
2015-10-30 09:43:10 +01:00
/**
2013-01-18 09:00:23 +01:00
Scans the stringlist ( linear scan ) to see if it contains ( at
least ) one occurence of ' s ' . Will never return true if the input
string @ s equals NULL , altough the stringlist itself can contain
NULL elements .
*/
bool stringlist_contains ( const stringlist_type * stringlist , const char * s ) {
int size = stringlist_get_size ( stringlist ) ;
int index = 0 ;
bool contains = false ;
2015-10-30 09:43:10 +01:00
2013-01-18 09:00:23 +01:00
while ( ( index < size ) & & ( ! contains ) ) {
const char * istring = stringlist_iget ( stringlist , index ) ;
if ( istring ! = NULL )
if ( strcmp ( istring , s ) = = 0 ) contains = true ;
index + + ;
}
return contains ;
}
/**
Finds the indicies of the entries matching ' s ' .
*/
int_vector_type * stringlist_find ( const stringlist_type * stringlist , const char * s ) {
int_vector_type * indicies = int_vector_alloc ( 0 , - 1 ) ;
int size = stringlist_get_size ( stringlist ) ;
int index = 0 ;
2015-10-30 09:43:10 +01:00
2013-01-18 09:00:23 +01:00
while ( index < size ) {
const char * istring = stringlist_iget ( stringlist , index ) ;
if ( istring ! = NULL )
if ( strcmp ( istring , s ) = = 0 )
int_vector_append ( indicies , index ) ;
index + + ;
}
return indicies ;
}
/**
Find the index of the first index matching ' s ' .
Returns - 1 if ' s ' cannot be found .
*/
int stringlist_find_first ( const stringlist_type * stringlist , const char * s ) {
bool found = false ;
int size = stringlist_get_size ( stringlist ) ;
int index = 0 ;
while ( index < size & & ! found )
{
const char * istring = stringlist_iget ( stringlist , index ) ;
if ( istring ! = NULL )
if ( strcmp ( istring , s ) = = 0 )
{
found = true ;
break ;
}
index + + ;
}
if ( found )
return index ;
else
return - 1 ;
}
bool stringlist_equal ( const stringlist_type * s1 , const stringlist_type * s2 ) {
int size1 = stringlist_get_size ( s1 ) ;
int size2 = stringlist_get_size ( s2 ) ;
if ( size1 = = size2 ) {
bool equal = true ;
int i ;
for ( i = 0 ; i < size1 ; i + + ) {
if ( strcmp ( stringlist_iget ( s1 , i ) , stringlist_iget ( s2 , i ) ) ! = 0 ) {
equal = false ;
break ;
}
}
return equal ;
} else
return false ;
}
/**
The interval is halfopen : [ start_index , end_index ) .
*/
/* Based on buffer?? */
char * stringlist_alloc_joined_substring ( const stringlist_type * s , int start_index , int end_index , const char * sep ) {
if ( start_index > = stringlist_get_size ( s ) )
2016-11-22 12:50:28 +01:00
return util_alloc_string_copy ( " " ) ;
2013-01-18 09:00:23 +01:00
{
char * string = NULL ;
int i ;
2015-10-30 09:43:10 +01:00
2013-01-18 09:00:23 +01:00
/* Start with allocating a string long enough to hold all the substrings. */
{
int sep_length = strlen ( sep ) ;
int total_length = 0 ;
for ( i = start_index ; i < end_index ; i + + )
total_length + = ( strlen ( stringlist_iget ( s , i ) ) + sep_length ) ;
2015-10-30 09:43:10 +01:00
2013-01-18 09:00:23 +01:00
total_length + = ( 1 - sep_length ) ;
2017-08-29 07:48:38 +02:00
string = ( char * ) util_malloc ( total_length * sizeof * string ) ;
2013-01-18 09:00:23 +01:00
string [ 0 ] = ' \0 ' ;
}
2015-10-30 09:43:10 +01:00
2013-01-18 09:00:23 +01:00
for ( i = start_index ; i < end_index ; i + + ) {
strcat ( string , stringlist_iget ( s , i ) ) ;
if ( i < ( end_index - 1 ) )
strcat ( string , sep ) ;
}
2015-10-30 09:43:10 +01:00
2013-01-18 09:00:23 +01:00
return string ;
}
}
char * stringlist_alloc_joined_string ( const stringlist_type * s , const char * sep ) {
return stringlist_alloc_joined_substring ( s , 0 , stringlist_get_size ( s ) , sep ) ;
}
/**
This function will allocate a stringlist instance based on
splitting the input string . If the input string is NULL the
function will return a stringlist instance with zero elements .
Observe that the splitting is based on __ANY__ character in @ sep ;
NOT the full exact string @ sep .
The newly allocated stringlist will take ownership of the strings
in the list . The actual functionality is in the util_split_string ( )
function .
*/
2015-10-30 09:43:10 +01:00
2013-01-18 09:00:23 +01:00
stringlist_type * stringlist_alloc_from_split ( const char * input_string , const char * sep ) {
stringlist_type * slist = stringlist_alloc_new ( ) ;
if ( input_string ! = NULL ) {
char * * items ;
int num_items , i ;
util_split_string ( input_string , sep , & num_items , & items ) ;
for ( i = 0 ; i < num_items ; i + + )
stringlist_append_copy ( slist , items [ i ] ) ;
util_free_stringlist ( items , num_items ) ;
}
return slist ;
}
/*****************************************************************/
void stringlist_buffer_fwrite ( const stringlist_type * s , buffer_type * buffer ) {
int i ;
int size = stringlist_get_size ( s ) ;
buffer_fwrite_int ( buffer , size ) ;
2015-10-30 09:43:10 +01:00
for ( i = 0 ; i < size ; i + + )
2013-01-18 09:00:23 +01:00
buffer_fwrite_string ( buffer , stringlist_iget ( s , i ) ) ;
}
void stringlist_fwrite ( const stringlist_type * s , FILE * stream ) {
int i ;
int size = stringlist_get_size ( s ) ;
util_fwrite_int ( size , stream ) ;
2015-10-30 09:43:10 +01:00
for ( i = 0 ; i < size ; i + + )
2013-01-18 09:00:23 +01:00
util_fwrite_string ( stringlist_iget ( s , i ) , stream ) ;
}
2015-10-30 09:43:10 +01:00
/*
2013-01-18 09:00:23 +01:00
When a stringlist is loaded from file the current content of the
stringlist is discarded ; and the stringlist becomes the owner of
all the data read in .
*/
void stringlist_fread ( stringlist_type * s , FILE * stream ) {
int size = util_fread_int ( stream ) ;
int i ;
stringlist_clear ( s ) ;
for ( i = 0 ; i < size ; i + + )
stringlist_append_owned_ref ( s , util_fread_alloc_string ( stream ) ) ;
}
void stringlist_buffer_fread ( stringlist_type * s , buffer_type * buffer ) {
int size = buffer_fread_int ( buffer ) ;
int i ;
stringlist_clear ( s ) ;
for ( i = 0 ; i < size ; i + + )
stringlist_append_owned_ref ( s , buffer_fread_alloc_string ( buffer ) ) ;
}
stringlist_type * stringlist_fread_alloc ( FILE * stream ) {
stringlist_type * s = stringlist_alloc_empty ( true ) ;
stringlist_fread ( s , stream ) ;
return s ;
}
static int strcmp__ ( const void * __s1 , const void * __s2 ) {
const char * s1 = ( const char * ) __s1 ;
const char * s2 = ( const char * ) __s2 ;
return strcmp ( s1 , s2 ) ;
}
/**
Will sort the stringlist inplace . The prototype of the comparison
function is
int ( cmp ) ( const void * , const void * ) ;
i . e . ths strings are implemented as ( void * ) . If string_cmp = = NULL
the sort function will use the ordinary strcmp ( ) function for
comparison .
*/
void stringlist_sort ( stringlist_type * s , string_cmp_ftype * string_cmp )
{
if ( string_cmp = = NULL )
vector_sort ( s - > strings , strcmp__ ) ;
else
vector_sort ( s - > strings , string_cmp ) ;
}
void stringlist_python_sort ( stringlist_type * s , int cmp_flag ) {
if ( cmp_flag = = 0 )
stringlist_sort ( s , NULL ) ;
else if ( cmp_flag = = 1 )
stringlist_sort ( s , ( string_cmp_ftype * ) util_strcmp_int ) ;
else if ( cmp_flag = = 2 )
stringlist_sort ( s , ( string_cmp_ftype * ) util_strcmp_float ) ;
else
util_abort ( " %s: unrecognized cmp_flag:%d \n " , __func__ , cmp_flag ) ;
}
2013-04-04 08:24:40 +02:00
void stringlist_reverse ( stringlist_type * s ) {
vector_inplace_reverse ( s - > strings ) ;
}
2013-01-18 09:00:23 +01:00
/*****************************************************************/
/*
This function uses the stdlib function glob ( ) to select file / path
names matching a pattern . The stringlist is cleared when the
function starts .
*/
2016-04-19 14:48:14 +02:00
# ifdef ERT_HAVE_GLOB
2013-01-18 09:00:23 +01:00
int stringlist_select_matching ( stringlist_type * names , const char * pattern ) {
int match_count = 0 ;
stringlist_clear ( names ) ;
{
int i ;
2017-08-29 07:48:38 +02:00
glob_t * pglob = ( glob_t * ) util_malloc ( sizeof * pglob ) ;
2013-01-18 09:00:23 +01:00
int glob_flags = 0 ;
glob ( pattern , glob_flags , NULL , pglob ) ;
match_count = pglob - > gl_pathc ;
for ( i = 0 ; i < pglob - > gl_pathc ; i + + )
stringlist_append_copy ( names , pglob - > gl_pathv [ i ] ) ;
globfree ( pglob ) ; /* Only frees the _internal_ data structures of the pglob object. */
free ( pglob ) ;
}
return match_count ;
}
# endif
int stringlist_select_matching_files ( stringlist_type * names , const char * path , const char * file_pattern ) {
2016-04-19 14:48:14 +02:00
# ifdef ERT_HAVE_GLOB
2013-01-18 09:00:23 +01:00
char * pattern = util_alloc_filename ( path , file_pattern , NULL ) ;
int match_count = stringlist_select_matching ( names , pattern ) ;
free ( pattern ) ;
return match_count ;
# else
{
WIN32_FIND_DATA file_data ;
HANDLE file_handle ;
char * pattern = util_alloc_filename ( path , file_pattern , NULL ) ;
2015-10-30 09:43:10 +01:00
2013-01-18 09:00:23 +01:00
stringlist_clear ( names ) ;
file_handle = FindFirstFile ( pattern , & file_data ) ;
if ( file_handle ! = INVALID_HANDLE_VALUE ) {
do {
char * full_path = util_alloc_filename ( path , file_data . cFileName , NULL ) ;
stringlist_append_owned_ref ( names , full_path ) ;
} while ( FindNextFile ( file_handle , & file_data ) ! = 0 ) ;
}
FindClose ( file_handle ) ;
free ( pattern ) ;
2015-10-30 09:43:10 +01:00
2013-01-18 09:00:23 +01:00
return stringlist_get_size ( names ) ;
}
# endif
}
2013-10-07 13:31:13 +02:00
int stringlist_append_matching_elements ( stringlist_type * target , const stringlist_type * src , const char * pattern ) {
int ielm ;
int match_count = 0 ;
for ( ielm = 0 ; ielm < stringlist_get_size ( src ) ; ielm + + ) {
const char * item = stringlist_iget ( src , ielm ) ;
if ( util_fnmatch ( pattern , item ) = = 0 ) {
stringlist_append_copy ( target , item ) ;
match_count + + ;
}
}
return match_count ;
}
2015-10-30 09:43:10 +01:00
2013-10-07 13:31:13 +02:00
int stringlist_select_matching_elements ( stringlist_type * target , const stringlist_type * src , const char * pattern ) {
stringlist_clear ( target ) ;
return stringlist_append_matching_elements ( target , src , pattern ) ;
}
2013-01-18 09:00:23 +01:00
# ifdef __cplusplus
}
# endif