2010-11-14 21:58:33 +03:00
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd .
Copyright 2010 Lennart Poettering
2013-02-07 00:15:23 +04:00
Copyright 2013 Thomas H . P . Andersen
2010-11-14 21:58:33 +03:00
systemd is free software ; you can redistribute it and / or modify it
2012-04-12 02:20:58 +04:00
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation ; either version 2.1 of the License , or
2010-11-14 21:58:33 +03:00
( at your option ) any later version .
systemd 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
2012-04-12 02:20:58 +04:00
Lesser General Public License for more details .
2010-11-14 21:58:33 +03:00
2012-04-12 02:20:58 +04:00
You should have received a copy of the GNU Lesser General Public License
2010-11-14 21:58:33 +03:00
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
# include <string.h>
2011-01-07 01:51:52 +03:00
2010-11-14 21:58:33 +03:00
# include "util.h"
2011-01-07 01:51:52 +03:00
# include "specifier.h"
2013-01-31 00:45:40 +04:00
# include "strv.h"
2010-11-14 21:58:33 +03:00
2013-01-31 00:36:56 +04:00
static void test_specifier_printf ( void ) {
2013-09-17 20:02:02 +04:00
static const Specifier table [ ] = {
2011-01-07 01:51:52 +03:00
{ ' a ' , specifier_string , ( char * ) " AAAA " } ,
{ ' b ' , specifier_string , ( char * ) " BBBB " } ,
2013-09-17 19:03:46 +04:00
{ ' m ' , specifier_machine_id , NULL } ,
{ ' B ' , specifier_boot_id , NULL } ,
{ ' H ' , specifier_host_name , NULL } ,
{ ' v ' , specifier_kernel_release , NULL } ,
2013-09-17 20:02:02 +04:00
{ }
2011-01-07 01:51:52 +03:00
} ;
2013-09-17 20:02:02 +04:00
_cleanup_free_ char * w = NULL ;
int r ;
2013-09-17 19:03:46 +04:00
r = specifier_printf ( " xxx a=%a b=%b yyy " , table , NULL , & w ) ;
assert_se ( r > = 0 ) ;
assert_se ( w ) ;
2013-02-17 23:15:52 +04:00
puts ( w ) ;
2013-09-17 19:03:46 +04:00
assert_se ( streq ( w , " xxx a=AAAA b=BBBB yyy " ) ) ;
2013-02-17 23:15:52 +04:00
2013-09-17 19:03:46 +04:00
free ( w ) ;
r = specifier_printf ( " machine=%m, boot=%B, host=%H, version=%v " , table , NULL , & w ) ;
assert_se ( r > = 0 ) ;
2013-02-17 23:15:52 +04:00
assert_se ( w ) ;
2013-09-17 19:03:46 +04:00
puts ( w ) ;
2013-01-31 00:36:56 +04:00
}
2013-08-31 22:28:09 +04:00
static const char * const input_table_multiple [ ] = {
" one " ,
" two " ,
" three " ,
NULL ,
} ;
static const char * const input_table_one [ ] = {
" one " ,
NULL ,
} ;
static const char * const input_table_none [ ] = {
NULL ,
} ;
static const char * const input_table_quotes [ ] = {
" \" " ,
" ' " ,
" \" \" " ,
" \\ " ,
" \\ \\ " ,
NULL ,
} ;
# define QUOTES_STRING \
" \" \\ \" \" " \
" \" \\ \' \" " \
" \" \\ \" \\ \" \" " \
" \" \\ \\ \" " \
" \" \\ \\ \\ \\ \" "
static const char * const input_table_spaces [ ] = {
" " ,
" ' ' " ,
" \" " ,
" \" " ,
" \\ \\ " ,
NULL ,
} ;
# define SPACES_STRING \
" \" \" " \
" \" \\ ' \\ ' \" " \
" \" \\ \" \" " \
" \" \\ \" \" " \
" \" \\ \\ \\ \\ \" "
2013-02-07 00:15:23 +04:00
2013-08-31 22:28:09 +04:00
static void test_strv_find ( void ) {
assert_se ( strv_find ( ( char * * ) input_table_multiple , " three " ) ) ;
assert_se ( ! strv_find ( ( char * * ) input_table_multiple , " four " ) ) ;
2013-02-07 00:15:23 +04:00
}
static void test_strv_find_prefix ( void ) {
2013-08-31 22:28:09 +04:00
assert_se ( strv_find_prefix ( ( char * * ) input_table_multiple , " o " ) ) ;
assert_se ( strv_find_prefix ( ( char * * ) input_table_multiple , " one " ) ) ;
assert_se ( strv_find_prefix ( ( char * * ) input_table_multiple , " " ) ) ;
assert_se ( ! strv_find_prefix ( ( char * * ) input_table_multiple , " xxx " ) ) ;
assert_se ( ! strv_find_prefix ( ( char * * ) input_table_multiple , " onee " ) ) ;
2013-01-31 00:36:56 +04:00
}
2010-11-14 21:58:33 +03:00
2013-01-31 00:45:40 +04:00
static void test_strv_join ( void ) {
2013-02-07 00:15:23 +04:00
_cleanup_free_ char * p = NULL , * q = NULL , * r = NULL , * s = NULL , * t = NULL ;
2013-01-31 00:45:40 +04:00
2013-02-07 00:15:23 +04:00
p = strv_join ( ( char * * ) input_table_multiple , " , " ) ;
2013-02-18 19:48:12 +04:00
assert_se ( p ) ;
2013-02-13 19:13:39 +04:00
assert_se ( streq ( p , " one, two, three " ) ) ;
2013-01-31 00:45:40 +04:00
2013-02-07 00:15:23 +04:00
q = strv_join ( ( char * * ) input_table_multiple , " ; " ) ;
2013-02-18 19:48:12 +04:00
assert_se ( q ) ;
2013-02-13 19:13:39 +04:00
assert_se ( streq ( q , " one;two;three " ) ) ;
2013-01-31 00:45:40 +04:00
r = strv_join ( ( char * * ) input_table_multiple , NULL ) ;
2013-02-18 19:48:12 +04:00
assert_se ( r ) ;
2013-02-13 19:13:39 +04:00
assert_se ( streq ( r , " one two three " ) ) ;
2013-02-07 00:15:23 +04:00
s = strv_join ( ( char * * ) input_table_one , " , " ) ;
2013-02-18 19:48:12 +04:00
assert_se ( s ) ;
2013-02-13 19:13:39 +04:00
assert_se ( streq ( s , " one " ) ) ;
2013-02-07 00:15:23 +04:00
t = strv_join ( ( char * * ) input_table_none , " , " ) ;
2013-02-18 19:48:12 +04:00
assert_se ( t ) ;
2013-02-13 19:13:39 +04:00
assert_se ( streq ( t , " " ) ) ;
2013-01-31 00:45:40 +04:00
}
2013-08-31 22:28:09 +04:00
static void test_strv_quote_unquote ( const char * const * split , const char * quoted ) {
_cleanup_free_ char * p ;
_cleanup_strv_free_ char * * s ;
char * * t ;
p = strv_join_quoted ( ( char * * ) split ) ;
2013-11-28 01:37:52 +04:00
assert_se ( p ) ;
2013-08-31 22:28:09 +04:00
printf ( " -%s- --- -%s- \n " , p , quoted ) ; /* fprintf deals with NULL, puts does not */
assert_se ( p ) ;
assert_se ( streq ( p , quoted ) ) ;
s = strv_split_quoted ( quoted ) ;
assert_se ( s ) ;
STRV_FOREACH ( t , s ) {
assert_se ( * t ) ;
assert_se ( streq ( * t , * split ) ) ;
split + + ;
}
}
2013-11-28 01:37:52 +04:00
static void test_strv_quote_unquote2 ( const char * quoted , const char * * list ) {
_cleanup_strv_free_ char * * s ;
unsigned i = 0 ;
char * * t ;
s = strv_split_quoted ( quoted ) ;
assert_se ( s ) ;
STRV_FOREACH ( t , s )
assert_se ( streq ( list [ i + + ] , * t ) ) ;
assert_se ( list [ i ] = = NULL ) ;
}
2013-10-31 13:03:08 +04:00
static void test_strv_split ( void ) {
char * * s ;
unsigned i = 0 ;
_cleanup_strv_free_ char * * l = NULL ;
const char str [ ] = " one,two,three " ;
l = strv_split ( str , " , " ) ;
assert ( l ) ;
STRV_FOREACH ( s , l ) {
assert_se ( streq ( * s , input_table_multiple [ i + + ] ) ) ;
}
}
static void test_strv_split_newlines ( void ) {
unsigned i = 0 ;
char * * s ;
_cleanup_strv_free_ char * * l = NULL ;
const char str [ ] = " one \n two \n three " ;
l = strv_split_newlines ( str ) ;
assert ( l ) ;
STRV_FOREACH ( s , l ) {
assert_se ( streq ( * s , input_table_multiple [ i + + ] ) ) ;
}
}
2013-02-19 02:53:33 +04:00
static void test_strv_split_nulstr ( void ) {
_cleanup_strv_free_ char * * l = NULL ;
const char nulstr [ ] = " str0 \0 str1 \0 str2 \0 str3 \0 " ;
l = strv_split_nulstr ( nulstr ) ;
2013-02-18 19:48:12 +04:00
assert_se ( l ) ;
2013-02-19 02:53:33 +04:00
assert_se ( streq ( l [ 0 ] , " str0 " ) ) ;
assert_se ( streq ( l [ 1 ] , " str1 " ) ) ;
assert_se ( streq ( l [ 2 ] , " str2 " ) ) ;
assert_se ( streq ( l [ 3 ] , " str3 " ) ) ;
}
2013-10-31 13:03:08 +04:00
static void test_strv_remove_prefix ( void ) {
unsigned i = 0 ;
char * * s ;
_cleanup_strv_free_ char * * l = NULL ;
l = strv_new ( " _one " , " _two " , " _three " , NULL ) ;
assert ( l ) ;
l = strv_remove_prefix ( l , " _ " ) ;
assert ( l ) ;
STRV_FOREACH ( s , l ) {
assert_se ( streq ( * s , input_table_multiple [ i + + ] ) ) ;
}
}
2013-02-07 03:33:58 +04:00
static void test_strv_parse_nulstr ( void ) {
_cleanup_strv_free_ char * * l = NULL ;
const char nulstr [ ] = " fuck \0 fuck2 \0 fuck3 \0 \0 fuck5 \0 \0 xxx " ;
l = strv_parse_nulstr ( nulstr , sizeof ( nulstr ) - 1 ) ;
2013-02-18 19:48:12 +04:00
assert_se ( l ) ;
2013-02-07 03:33:58 +04:00
puts ( " Parse nulstr: " ) ;
strv_print ( l ) ;
2013-02-13 19:13:39 +04:00
assert_se ( streq ( l [ 0 ] , " fuck " ) ) ;
assert_se ( streq ( l [ 1 ] , " fuck2 " ) ) ;
assert_se ( streq ( l [ 2 ] , " fuck3 " ) ) ;
assert_se ( streq ( l [ 3 ] , " " ) ) ;
assert_se ( streq ( l [ 4 ] , " fuck5 " ) ) ;
assert_se ( streq ( l [ 5 ] , " " ) ) ;
assert_se ( streq ( l [ 6 ] , " xxx " ) ) ;
2013-02-07 03:33:58 +04:00
}
2013-02-07 00:15:23 +04:00
static void test_strv_overlap ( void ) {
const char * const input_table [ ] = {
" one " ,
" two " ,
" three " ,
NULL
} ;
const char * const input_table_overlap [ ] = {
" two " ,
NULL
} ;
const char * const input_table_unique [ ] = {
" four " ,
" five " ,
" six " ,
NULL
} ;
2013-02-13 19:13:39 +04:00
assert_se ( strv_overlap ( ( char * * ) input_table , ( char * * ) input_table_overlap ) ) ;
assert_se ( ! strv_overlap ( ( char * * ) input_table , ( char * * ) input_table_unique ) ) ;
2013-02-07 00:15:23 +04:00
}
static void test_strv_sort ( void ) {
2013-04-05 08:31:59 +04:00
const char * input_table [ ] = {
2013-02-07 00:15:23 +04:00
" durian " ,
" apple " ,
" citrus " ,
" CAPITAL LETTERS FIRST " ,
" banana " ,
NULL
} ;
strv_sort ( ( char * * ) input_table ) ;
2013-02-13 19:13:39 +04:00
assert_se ( streq ( input_table [ 0 ] , " CAPITAL LETTERS FIRST " ) ) ;
assert_se ( streq ( input_table [ 1 ] , " apple " ) ) ;
assert_se ( streq ( input_table [ 2 ] , " banana " ) ) ;
assert_se ( streq ( input_table [ 3 ] , " citrus " ) ) ;
assert_se ( streq ( input_table [ 4 ] , " durian " ) ) ;
2013-01-31 00:36:56 +04:00
}
2010-11-16 01:49:02 +03:00
2013-02-13 19:13:37 +04:00
static void test_strv_merge_concat ( void ) {
2013-02-13 19:13:39 +04:00
_cleanup_strv_free_ char * * a = NULL , * * b = NULL , * * c = NULL ;
2013-02-13 19:13:37 +04:00
2013-02-13 19:13:39 +04:00
a = strv_new ( " without " , " suffix " , NULL ) ;
b = strv_new ( " with " , " suffix " , NULL ) ;
2013-02-18 19:48:12 +04:00
assert_se ( a ) ;
assert_se ( b ) ;
2013-02-13 19:13:37 +04:00
2013-02-13 19:13:39 +04:00
c = strv_merge_concat ( a , b , " _suffix " ) ;
2013-02-18 19:48:12 +04:00
assert_se ( c ) ;
2013-02-13 19:13:37 +04:00
2013-02-13 19:13:39 +04:00
assert_se ( streq ( c [ 0 ] , " without " ) ) ;
assert_se ( streq ( c [ 1 ] , " suffix " ) ) ;
assert_se ( streq ( c [ 2 ] , " with_suffix " ) ) ;
assert_se ( streq ( c [ 3 ] , " suffix_suffix " ) ) ;
2013-02-13 19:13:37 +04:00
}
2013-02-13 19:13:36 +04:00
static void test_strv_merge ( void ) {
_cleanup_strv_free_ char * * a = NULL , * * b = NULL , * * c = NULL ;
2013-02-13 19:13:39 +04:00
a = strv_new ( " abc " , " def " , " ghi " , NULL ) ;
b = strv_new ( " jkl " , " mno " , " pqr " , NULL ) ;
2013-02-18 19:48:12 +04:00
assert_se ( a ) ;
assert_se ( b ) ;
2013-02-13 19:13:36 +04:00
2013-02-13 19:13:39 +04:00
c = strv_merge ( a , b ) ;
2013-02-18 19:48:12 +04:00
assert_se ( c ) ;
2013-02-13 19:13:36 +04:00
2013-02-13 19:13:39 +04:00
assert_se ( streq ( c [ 0 ] , " abc " ) ) ;
assert_se ( streq ( c [ 1 ] , " def " ) ) ;
assert_se ( streq ( c [ 2 ] , " ghi " ) ) ;
assert_se ( streq ( c [ 3 ] , " jkl " ) ) ;
assert_se ( streq ( c [ 4 ] , " mno " ) ) ;
assert_se ( streq ( c [ 5 ] , " pqr " ) ) ;
2013-02-13 19:13:36 +04:00
2013-02-13 19:13:39 +04:00
assert_se ( strv_length ( c ) = = 6 ) ;
2013-02-13 19:13:36 +04:00
}
2013-02-13 19:13:38 +04:00
static void test_strv_append ( void ) {
_cleanup_strv_free_ char * * a = NULL , * * b = NULL , * * c = NULL ;
a = strv_new ( " test " , " test1 " , NULL ) ;
2013-02-18 19:48:12 +04:00
assert_se ( a ) ;
2013-02-13 19:13:38 +04:00
b = strv_append ( a , " test2 " ) ;
c = strv_append ( NULL , " test3 " ) ;
2013-02-18 19:48:12 +04:00
assert_se ( b ) ;
assert_se ( c ) ;
2013-02-13 19:13:38 +04:00
2013-02-13 19:13:39 +04:00
assert_se ( streq ( b [ 0 ] , " test " ) ) ;
assert_se ( streq ( b [ 1 ] , " test1 " ) ) ;
assert_se ( streq ( b [ 2 ] , " test2 " ) ) ;
assert_se ( streq ( c [ 0 ] , " test3 " ) ) ;
2013-02-13 19:13:38 +04:00
}
2013-10-27 15:45:53 +04:00
static void test_strv_foreach ( void ) {
2013-10-29 22:53:43 +04:00
_cleanup_strv_free_ char * * a ;
unsigned i = 0 ;
char * * check ;
2013-10-27 15:45:53 +04:00
2013-10-29 22:53:43 +04:00
a = strv_new ( " one " , " two " , " three " , NULL ) ;
2013-10-27 15:45:53 +04:00
2013-10-29 22:53:43 +04:00
assert_se ( a ) ;
2013-10-27 15:45:53 +04:00
2013-10-29 22:53:43 +04:00
STRV_FOREACH ( check , a ) {
assert_se ( streq ( * check , input_table_multiple [ i + + ] ) ) ;
}
2013-10-27 15:45:53 +04:00
}
static void test_strv_foreach_backwards ( void ) {
2013-10-29 22:53:43 +04:00
_cleanup_strv_free_ char * * a ;
unsigned i = 2 ;
char * * check ;
2013-10-27 15:45:53 +04:00
2013-10-29 22:53:43 +04:00
a = strv_new ( " one " , " two " , " three " , NULL ) ;
2013-10-27 15:45:53 +04:00
2013-10-29 22:53:43 +04:00
assert_se ( a ) ;
2013-10-27 15:45:53 +04:00
2013-10-29 22:53:43 +04:00
STRV_FOREACH_BACKWARDS ( check , a ) {
2013-12-13 02:08:47 +04:00
assert_se ( streq_ptr ( * check , input_table_multiple [ i - - ] ) ) ;
2013-10-29 22:53:43 +04:00
}
2013-10-27 15:45:53 +04:00
}
2013-03-16 13:00:03 +04:00
static void test_strv_foreach_pair ( void ) {
_cleanup_strv_free_ char * * a = NULL ;
char * * x , * * y ;
a = strv_new ( " pair_one " , " pair_one " ,
" pair_two " , " pair_two " ,
" pair_three " , " pair_three " ,
NULL ) ;
STRV_FOREACH_PAIR ( x , y , a ) {
assert_se ( streq ( * x , * y ) ) ;
}
}
2013-10-29 23:09:16 +04:00
static void test_strv_from_stdarg_alloca_one ( char * * l , const char * first , . . . ) {
2013-10-29 22:53:43 +04:00
char * * j ;
unsigned i ;
j = strv_from_stdarg_alloca ( first ) ;
for ( i = 0 ; ; i + + ) {
assert_se ( streq_ptr ( l [ i ] , j [ i ] ) ) ;
if ( ! l [ i ] )
break ;
}
}
static void test_strv_from_stdarg_alloca ( void ) {
2013-10-29 23:09:16 +04:00
test_strv_from_stdarg_alloca_one ( STRV_MAKE ( " foo " , " bar " ) , " foo " , " bar " , NULL ) ;
test_strv_from_stdarg_alloca_one ( STRV_MAKE ( " foo " ) , " foo " , NULL ) ;
test_strv_from_stdarg_alloca_one ( STRV_MAKE_EMPTY , NULL ) ;
2013-10-29 22:53:43 +04:00
}
2013-01-31 00:36:56 +04:00
int main ( int argc , char * argv [ ] ) {
test_specifier_printf ( ) ;
2013-10-27 15:45:53 +04:00
test_strv_foreach ( ) ;
test_strv_foreach_backwards ( ) ;
2013-03-16 13:00:03 +04:00
test_strv_foreach_pair ( ) ;
2013-02-07 00:15:23 +04:00
test_strv_find ( ) ;
test_strv_find_prefix ( ) ;
2013-01-31 00:45:40 +04:00
test_strv_join ( ) ;
2013-08-31 22:28:09 +04:00
test_strv_quote_unquote ( input_table_multiple , " \" one \" \" two \" \" three \" " ) ;
test_strv_quote_unquote ( input_table_one , " \" one \" " ) ;
test_strv_quote_unquote ( input_table_none , " " ) ;
test_strv_quote_unquote ( input_table_quotes , QUOTES_STRING ) ;
test_strv_quote_unquote ( input_table_spaces , SPACES_STRING ) ;
2013-11-28 01:37:52 +04:00
test_strv_quote_unquote2 ( " foo=bar \" waldo \" zzz " , ( const char * [ ] ) { " foo=bar " , " waldo " , " zzz " , NULL } ) ;
test_strv_quote_unquote2 ( " " , ( const char * [ ] ) { NULL } ) ;
test_strv_quote_unquote2 ( " " , ( const char * [ ] ) { NULL } ) ;
test_strv_quote_unquote2 ( " " , ( const char * [ ] ) { NULL } ) ;
test_strv_quote_unquote2 ( " x " , ( const char * [ ] ) { " x " , NULL } ) ;
test_strv_quote_unquote2 ( " x " , ( const char * [ ] ) { " x " , NULL } ) ;
test_strv_quote_unquote2 ( " x " , ( const char * [ ] ) { " x " , NULL } ) ;
test_strv_quote_unquote2 ( " \" x \" " , ( const char * [ ] ) { " x " , NULL } ) ;
test_strv_quote_unquote2 ( " \' x \' " , ( const char * [ ] ) { " x " , NULL } ) ;
test_strv_quote_unquote2 ( " \' x \" \' " , ( const char * [ ] ) { " x \" " , NULL } ) ;
test_strv_quote_unquote2 ( " \" x \' \" " , ( const char * [ ] ) { " x \' " , NULL } ) ;
2013-10-31 13:03:08 +04:00
test_strv_split ( ) ;
test_strv_split_newlines ( ) ;
2013-02-19 02:53:33 +04:00
test_strv_split_nulstr ( ) ;
2013-02-07 03:33:58 +04:00
test_strv_parse_nulstr ( ) ;
2013-10-31 13:03:08 +04:00
test_strv_remove_prefix ( ) ;
2013-02-07 00:15:23 +04:00
test_strv_overlap ( ) ;
test_strv_sort ( ) ;
2013-02-13 19:13:36 +04:00
test_strv_merge ( ) ;
2013-02-13 19:13:37 +04:00
test_strv_merge_concat ( ) ;
2013-02-13 19:13:38 +04:00
test_strv_append ( ) ;
2013-10-29 22:53:43 +04:00
test_strv_from_stdarg_alloca ( ) ;
2011-01-07 01:51:52 +03:00
2010-11-14 21:58:33 +03:00
return 0 ;
}