2004-10-08 12:13:00 +04:00
/*
Unix SMB / CIFS implementation .
2005-02-04 07:58:48 +03:00
Copyright ( C ) Andrew Tridgell 2005
2005-09-26 21:42:12 +04:00
Copyright ( C ) Jelmer Vernooij 2005
2004-10-08 12:13:00 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2004-10-08 12:13:00 +04:00
( at your option ) any later version .
This program 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 for more details .
You should have received a copy of the GNU General Public License
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2004-10-08 12:13:00 +04:00
*/
# include "includes.h"
2007-04-19 18:21:56 +04:00
# include "system/locale.h"
2004-10-08 12:13:00 +04:00
2008-10-12 02:56:56 +04:00
# undef strcasecmp
2006-02-28 16:12:39 +03:00
/**
* @ file
* @ brief String list manipulation
*/
/**
2005-02-04 07:58:48 +03:00
build a null terminated list of strings from a input string and a
2005-08-30 17:58:48 +04:00
separator list . The separator list must contain characters less than
2005-02-04 07:58:48 +03:00
or equal to 0x2f for this to work correctly on multi - byte strings
*/
2008-10-12 02:56:56 +04:00
_PUBLIC_ char * * str_list_make ( TALLOC_CTX * mem_ctx , const char * string , const char * sep )
2005-02-04 07:58:48 +03:00
{
int num_elements = 0 ;
2008-10-12 02:56:56 +04:00
char * * ret = NULL ;
2004-10-08 12:13:00 +04:00
2005-02-04 07:58:48 +03:00
if ( sep = = NULL ) {
sep = LIST_SEP ;
}
2004-10-08 12:13:00 +04:00
2008-10-12 02:56:56 +04:00
ret = talloc_array ( mem_ctx , char * , 1 ) ;
2005-02-04 07:58:48 +03:00
if ( ret = = NULL ) {
2004-10-08 12:13:00 +04:00
return NULL ;
}
2005-02-04 07:58:48 +03:00
while ( string & & * string ) {
size_t len = strcspn ( string , sep ) ;
2008-10-12 02:56:56 +04:00
char * * ret2 ;
2004-10-08 12:13:00 +04:00
2005-02-04 07:58:48 +03:00
if ( len = = 0 ) {
string + = strspn ( string , sep ) ;
continue ;
}
2008-10-12 02:56:56 +04:00
ret2 = talloc_realloc ( mem_ctx , ret , char * , num_elements + 2 ) ;
2005-02-04 07:58:48 +03:00
if ( ret2 = = NULL ) {
talloc_free ( ret ) ;
2004-10-08 12:13:00 +04:00
return NULL ;
}
2005-02-04 07:58:48 +03:00
ret = ret2 ;
ret [ num_elements ] = talloc_strndup ( ret , string , len ) ;
if ( ret [ num_elements ] = = NULL ) {
talloc_free ( ret ) ;
return NULL ;
}
num_elements + + ;
string + = len ;
2004-10-08 12:13:00 +04:00
}
2005-02-04 07:58:48 +03:00
ret [ num_elements ] = NULL ;
return ret ;
2004-10-08 12:13:00 +04:00
}
2006-02-28 16:12:39 +03:00
/**
* build a null terminated list of strings from an argv - like input string
* Entries are seperated by spaces and can be enclosed by quotes .
* Does NOT support escaping
2005-09-26 21:42:12 +04:00
*/
2006-03-05 20:15:19 +03:00
_PUBLIC_ const char * * str_list_make_shell ( TALLOC_CTX * mem_ctx , const char * string , const char * sep )
2005-09-26 21:42:12 +04:00
{
int num_elements = 0 ;
const char * * ret = NULL ;
ret = talloc_array ( mem_ctx , const char * , 1 ) ;
if ( ret = = NULL ) {
return NULL ;
}
2005-09-26 22:16:23 +04:00
if ( sep = = NULL )
sep = " \t \n \r " ;
2005-09-26 21:42:12 +04:00
while ( string & & * string ) {
2005-09-26 22:16:23 +04:00
size_t len = strcspn ( string , sep ) ;
2005-09-26 21:42:12 +04:00
char * element ;
const char * * ret2 ;
if ( len = = 0 ) {
2005-09-26 22:16:23 +04:00
string + = strspn ( string , sep ) ;
2005-09-26 21:42:12 +04:00
continue ;
}
if ( * string = = ' \" ' ) {
string + + ;
len = strcspn ( string , " \" " ) ;
element = talloc_strndup ( ret , string , len ) ;
string + = len + 1 ;
} else {
element = talloc_strndup ( ret , string , len ) ;
string + = len ;
}
if ( element = = NULL ) {
talloc_free ( ret ) ;
return NULL ;
}
ret2 = talloc_realloc ( mem_ctx , ret , const char * , num_elements + 2 ) ;
if ( ret2 = = NULL ) {
talloc_free ( ret ) ;
return NULL ;
}
ret = ret2 ;
ret [ num_elements ] = element ;
num_elements + + ;
}
ret [ num_elements ] = NULL ;
return ret ;
}
2006-02-28 16:12:39 +03:00
/**
* join a list back to one string
*/
2006-03-05 20:15:19 +03:00
_PUBLIC_ char * str_list_join ( TALLOC_CTX * mem_ctx , const char * * list , char seperator )
2005-08-30 17:58:48 +04:00
{
char * ret = NULL ;
int i ;
if ( list [ 0 ] = = NULL )
return talloc_strdup ( mem_ctx , " " ) ;
ret = talloc_strdup ( mem_ctx , list [ 0 ] ) ;
for ( i = 1 ; list [ i ] ; i + + ) {
2007-09-15 03:21:00 +04:00
ret = talloc_asprintf_append_buffer ( ret , " %c%s " , seperator , list [ i ] ) ;
2005-08-30 17:58:48 +04:00
}
return ret ;
}
2006-02-28 16:12:39 +03:00
/** join a list back to one (shell-like) string; entries
2005-09-26 21:42:12 +04:00
* seperated by spaces , using quotes where necessary */
2006-03-05 20:15:19 +03:00
_PUBLIC_ char * str_list_join_shell ( TALLOC_CTX * mem_ctx , const char * * list , char sep )
2005-09-26 21:42:12 +04:00
{
char * ret = NULL ;
int i ;
if ( list [ 0 ] = = NULL )
return talloc_strdup ( mem_ctx , " " ) ;
if ( strchr ( list [ 0 ] , ' ' ) | | strlen ( list [ 0 ] ) = = 0 )
ret = talloc_asprintf ( mem_ctx , " \" %s \" " , list [ 0 ] ) ;
else
ret = talloc_strdup ( mem_ctx , list [ 0 ] ) ;
for ( i = 1 ; list [ i ] ; i + + ) {
if ( strchr ( list [ i ] , ' ' ) | | strlen ( list [ i ] ) = = 0 )
2007-09-15 03:21:00 +04:00
ret = talloc_asprintf_append_buffer ( ret , " %c \" %s \" " , sep , list [ i ] ) ;
2005-09-26 21:42:12 +04:00
else
2007-09-15 03:21:00 +04:00
ret = talloc_asprintf_append_buffer ( ret , " %c%s " , sep , list [ i ] ) ;
2005-09-26 21:42:12 +04:00
}
return ret ;
}
2005-08-30 17:58:48 +04:00
2006-02-28 16:12:39 +03:00
/**
2005-02-04 07:58:48 +03:00
return the number of elements in a string list
*/
2008-10-12 04:27:38 +04:00
_PUBLIC_ size_t str_list_length ( const char * const * list )
2004-10-08 12:13:00 +04:00
{
2005-02-04 07:58:48 +03:00
size_t ret ;
for ( ret = 0 ; list & & list [ ret ] ; ret + + ) /* noop */ ;
return ret ;
}
2004-10-08 12:13:00 +04:00
2006-02-28 16:12:39 +03:00
/**
2005-02-04 07:58:48 +03:00
copy a string list
*/
2009-04-08 17:18:13 +04:00
_PUBLIC_ char * * str_list_copy ( TALLOC_CTX * mem_ctx , const char * const * list )
2005-02-04 07:58:48 +03:00
{
int i ;
2008-10-12 02:56:56 +04:00
char * * ret ;
2007-12-12 16:09:15 +03:00
if ( list = = NULL )
return NULL ;
2008-10-12 02:56:56 +04:00
ret = talloc_array ( mem_ctx , char * , str_list_length ( list ) + 1 ) ;
2007-12-12 16:09:15 +03:00
if ( ret = = NULL )
return NULL ;
2005-02-04 07:58:48 +03:00
for ( i = 0 ; list & & list [ i ] ; i + + ) {
ret [ i ] = talloc_strdup ( ret , list [ i ] ) ;
if ( ret [ i ] = = NULL ) {
talloc_free ( ret ) ;
return NULL ;
}
2004-10-08 12:13:00 +04:00
}
2005-02-04 07:58:48 +03:00
ret [ i ] = NULL ;
return ret ;
2004-10-08 12:13:00 +04:00
}
2006-02-28 16:12:39 +03:00
/**
2004-10-08 12:13:00 +04:00
Return true if all the elements of the list match exactly .
2005-02-04 07:58:48 +03:00
*/
2007-08-27 21:21:16 +04:00
_PUBLIC_ bool str_list_equal ( const char * * list1 , const char * * list2 )
2004-10-08 12:13:00 +04:00
{
2005-02-04 07:58:48 +03:00
int i ;
2004-10-08 12:13:00 +04:00
2005-02-04 07:58:48 +03:00
if ( list1 = = NULL | | list2 = = NULL ) {
2004-10-08 12:13:00 +04:00
return ( list1 = = list2 ) ;
2005-02-04 07:58:48 +03:00
}
2004-10-08 12:13:00 +04:00
2005-02-04 07:58:48 +03:00
for ( i = 0 ; list1 [ i ] & & list2 [ i ] ; i + + ) {
if ( strcmp ( list1 [ i ] , list2 [ i ] ) ! = 0 ) {
2007-08-27 21:21:16 +04:00
return false ;
2005-02-04 07:58:48 +03:00
}
}
if ( list1 [ i ] | | list2 [ i ] ) {
2007-08-27 21:21:16 +04:00
return false ;
2004-10-08 12:13:00 +04:00
}
2007-08-27 21:21:16 +04:00
return true ;
2004-10-08 12:13:00 +04:00
}
2005-02-14 12:15:24 +03:00
2006-02-28 16:12:39 +03:00
/**
2009-04-08 17:18:13 +04:00
add an entry to a string list if not already in there
2005-02-14 12:15:24 +03:00
*/
2009-04-08 17:18:13 +04:00
_PUBLIC_ char * * str_list_add_unique ( char * * list , const char * s )
2005-02-14 12:15:24 +03:00
{
2009-04-08 17:18:13 +04:00
int i ;
size_t len ;
2005-02-14 12:15:24 +03:00
const char * * ret ;
2009-04-08 17:18:13 +04:00
for ( i = 0 ; list [ i ] ; i + + ) {
if ( strcmp ( list [ i ] , s ) = = 0 ) return list ;
}
len = i ;
2005-02-14 12:15:24 +03:00
ret = talloc_realloc ( NULL , list , const char * , len + 2 ) ;
if ( ret = = NULL ) return NULL ;
ret [ len ] = talloc_strdup ( ret , s ) ;
if ( ret [ len ] = = NULL ) return NULL ;
ret [ len + 1 ] = NULL ;
return ret ;
}
2009-04-08 17:18:13 +04:00
/**
add an entry to a string list
*/
_PUBLIC_ char * * str_list_add ( char * * list , const char * s )
{
size_t len = str_list_length ( list ) ;
char * * ret ;
ret = talloc_realloc ( NULL , list , char * , len + 2 ) ;
if ( ret = = NULL ) return NULL ;
ret [ len ] = talloc_strdup ( ret , s ) ;
if ( ret [ len ] = = NULL ) return NULL ;
ret [ len + 1 ] = NULL ;
return ret ;
}
2006-02-28 16:12:39 +03:00
/**
2005-02-14 12:15:24 +03:00
remove an entry from a string list
*/
2006-03-05 20:15:19 +03:00
_PUBLIC_ void str_list_remove ( const char * * list , const char * s )
2005-02-14 12:15:24 +03:00
{
int i ;
for ( i = 0 ; list [ i ] ; i + + ) {
if ( strcmp ( list [ i ] , s ) = = 0 ) break ;
}
if ( ! list [ i ] ) return ;
for ( ; list [ i ] ; i + + ) {
list [ i ] = list [ i + 1 ] ;
}
}
2006-02-28 16:12:39 +03:00
/**
2007-08-27 21:21:16 +04:00
return true if a string is in a list
2005-02-14 12:15:24 +03:00
*/
2007-08-27 21:21:16 +04:00
_PUBLIC_ bool str_list_check ( const char * * list , const char * s )
2005-02-14 12:15:24 +03:00
{
int i ;
for ( i = 0 ; list [ i ] ; i + + ) {
2007-08-27 21:21:16 +04:00
if ( strcmp ( list [ i ] , s ) = = 0 ) return true ;
2005-02-14 12:15:24 +03:00
}
2007-08-27 21:21:16 +04:00
return false ;
2005-02-14 12:15:24 +03:00
}
2005-05-28 12:47:01 +04:00
2006-02-28 16:12:39 +03:00
/**
2007-08-27 21:21:16 +04:00
return true if a string is in a list , case insensitively
2005-05-28 12:47:01 +04:00
*/
2007-08-27 21:21:16 +04:00
_PUBLIC_ bool str_list_check_ci ( const char * * list , const char * s )
2005-05-28 12:47:01 +04:00
{
int i ;
for ( i = 0 ; list [ i ] ; i + + ) {
2007-08-27 21:21:16 +04:00
if ( strcasecmp ( list [ i ] , s ) = = 0 ) return true ;
2005-05-28 12:47:01 +04:00
}
2007-08-27 21:21:16 +04:00
return false ;
2005-05-28 12:47:01 +04:00
}
2007-04-19 18:21:56 +04:00
2009-04-07 10:33:26 +04:00
/**
append one list to another - expanding list1
*/
2009-04-08 17:18:13 +04:00
_PUBLIC_ char * * str_list_append ( char * * list1 , const char * const * list2 )
2009-04-07 10:33:26 +04:00
{
size_t len1 = str_list_length ( list1 ) ;
size_t len2 = str_list_length ( list2 ) ;
2009-04-08 17:18:13 +04:00
char * * ret ;
2009-04-07 10:33:26 +04:00
int i ;
2009-04-08 17:18:13 +04:00
ret = talloc_realloc ( NULL , list1 , char * , len1 + len2 + 1 ) ;
2009-04-07 10:33:26 +04:00
if ( ret = = NULL ) return NULL ;
for ( i = len1 ; i < len1 + len2 ; i + + ) {
ret [ i ] = talloc_strdup ( ret , list2 [ i - len1 ] ) ;
if ( ret [ i ] = = NULL ) {
return NULL ;
}
}
ret [ i ] = NULL ;
return ret ;
}