mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
796 lines
22 KiB
C
796 lines
22 KiB
C
/*
|
|
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.
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <ert/util/ert_api_config.h>
|
|
#ifdef ERT_HAVE_GLOB
|
|
#include <glob.h>
|
|
#else
|
|
#include <Windows.h>
|
|
#endif
|
|
|
|
#include <ert/util/util.h>
|
|
#include <ert/util/stringlist.h>
|
|
#include <ert/util/vector.h>
|
|
#include <ert/util/buffer.h>
|
|
|
|
|
|
#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.
|
|
|
|
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 );
|
|
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);
|
|
}
|
|
|
|
fprintf(stream , "%s", stringlist_iget( stringlist , length - 1 ));
|
|
}
|
|
}
|
|
|
|
|
|
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 ) {
|
|
stringlist_type * stringlist = (stringlist_type*)util_malloc(sizeof * stringlist );
|
|
UTIL_TYPE_ID_INIT( stringlist , STRINGLIST_TYPE_ID);
|
|
|
|
if (alloc_vector)
|
|
stringlist->strings = vector_alloc_new();
|
|
else
|
|
stringlist->strings = NULL;
|
|
|
|
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);
|
|
for (iarg = 0; iarg < argc; iarg++)
|
|
stringlist_append_copy( stringlist , argv[iarg]);
|
|
|
|
return stringlist;
|
|
}
|
|
|
|
|
|
stringlist_type * stringlist_alloc_argv_ref(const char ** argv , int argc) {
|
|
int iarg;
|
|
stringlist_type * stringlist = stringlist_alloc_empty( true );
|
|
for (iarg = 0; iarg < argc; iarg++)
|
|
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 );
|
|
for (iarg = 0; iarg < argc; iarg++)
|
|
stringlist_append_owned_ref( stringlist , argv[iarg]);
|
|
|
|
return stringlist;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
Allocates a new stringlist instance where all the new string are
|
|
references to the string found in the existing stringlist
|
|
instance.
|
|
*/
|
|
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;
|
|
for (i = 0; i < num_strings; i++)
|
|
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.
|
|
|
|
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 ));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
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);
|
|
}
|
|
|
|
|
|
char * stringlist_pop( stringlist_type * stringlist) {
|
|
return (char*)vector_pop_back( stringlist->strings );
|
|
}
|
|
|
|
|
|
const char * stringlist_iget(const stringlist_type * stringlist , int index) {
|
|
return (const char*)vector_iget(stringlist->strings ,index);
|
|
}
|
|
|
|
const char * stringlist_front(const stringlist_type * stringlist) {
|
|
return (const char*)vector_iget(stringlist->strings , 0);
|
|
}
|
|
|
|
const char * stringlist_back(const stringlist_type * stringlist) {
|
|
return (const char*)vector_iget(stringlist->strings , vector_get_size( stringlist->strings ) - 1);
|
|
}
|
|
|
|
|
|
int stringlist_iget_as_int( const stringlist_type * stringlist , int index , bool * valid) {
|
|
const char * string_value = stringlist_iget( stringlist , index );
|
|
int value = -1;
|
|
|
|
if (valid != NULL)
|
|
*valid = false;
|
|
|
|
if (util_sscanf_int(string_value , &value))
|
|
if (valid != NULL)
|
|
*valid = true;
|
|
|
|
return value;
|
|
}
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
const char * stringlist_get_last( const stringlist_type * stringlist ) {
|
|
return (const char*)vector_get_last( stringlist->strings );
|
|
}
|
|
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
/*
|
|
Return NULL if the list has zero entries.
|
|
*/
|
|
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;
|
|
strings = (char**)util_calloc(size , sizeof * strings );
|
|
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 );
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
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;
|
|
|
|
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;
|
|
|
|
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 ))
|
|
return util_alloc_string_copy("");
|
|
{
|
|
char * string = NULL;
|
|
int i;
|
|
|
|
/* 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);
|
|
|
|
total_length += (1 - sep_length);
|
|
string = (char*)util_malloc( total_length * sizeof * string );
|
|
string[0] = '\0';
|
|
}
|
|
|
|
for (i = start_index; i < end_index; i ++) {
|
|
strcat( string , stringlist_iget( s , i));
|
|
if (i < (end_index - 1))
|
|
strcat( string , sep );
|
|
}
|
|
|
|
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.
|
|
*/
|
|
|
|
|
|
|
|
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 );
|
|
for (i=0; i < size; i++)
|
|
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);
|
|
for (i=0; i < size; i++)
|
|
util_fwrite_string(stringlist_iget(s , i) , stream);
|
|
}
|
|
|
|
/*
|
|
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 );
|
|
}
|
|
|
|
|
|
void stringlist_reverse( stringlist_type * s ) {
|
|
vector_inplace_reverse( s->strings );
|
|
}
|
|
|
|
|
|
/*****************************************************************/
|
|
|
|
/*
|
|
This function uses the stdlib function glob() to select file/path
|
|
names matching a pattern. The stringlist is cleared when the
|
|
function starts.
|
|
*/
|
|
|
|
#ifdef ERT_HAVE_GLOB
|
|
int stringlist_select_matching(stringlist_type * names , const char * pattern) {
|
|
int match_count = 0;
|
|
stringlist_clear( names );
|
|
|
|
{
|
|
int i;
|
|
glob_t * pglob = (glob_t*)util_malloc( sizeof * pglob );
|
|
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) {
|
|
#ifdef ERT_HAVE_GLOB
|
|
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 );
|
|
|
|
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 );
|
|
|
|
return stringlist_get_size( names );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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 );
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|