2009-07-01 02:01:20 +04:00
/*
* ( c ) 2009 Arnaldo Carvalho de Melo < acme @ redhat . com >
*
* Licensed under the GPLv2 .
*/
# include "strlist.h"
2013-12-27 23:55:14 +04:00
# include "util.h"
2009-07-01 02:01:20 +04:00
# include <errno.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
2012-07-31 08:31:33 +04:00
static
struct rb_node * strlist__node_new ( struct rblist * rblist , const void * entry )
2009-07-01 02:01:20 +04:00
{
2012-07-31 08:31:33 +04:00
const char * s = entry ;
struct rb_node * rc = NULL ;
struct strlist * strlist = container_of ( rblist , struct strlist , rblist ) ;
struct str_node * snode = malloc ( sizeof ( * snode ) ) ;
2009-07-01 02:01:20 +04:00
2012-07-31 08:31:33 +04:00
if ( snode ! = NULL ) {
if ( strlist - > dupstr ) {
2009-07-01 02:01:20 +04:00
s = strdup ( s ) ;
if ( s = = NULL )
goto out_delete ;
}
2012-07-31 08:31:33 +04:00
snode - > s = s ;
rc = & snode - > rb_node ;
2009-07-01 02:01:20 +04:00
}
2012-07-31 08:31:33 +04:00
return rc ;
2009-07-01 02:01:20 +04:00
out_delete :
2012-07-31 08:31:33 +04:00
free ( snode ) ;
2009-07-01 02:01:20 +04:00
return NULL ;
}
2013-01-25 04:59:59 +04:00
static void str_node__delete ( struct str_node * snode , bool dupstr )
2009-07-01 02:01:20 +04:00
{
if ( dupstr )
2014-01-09 18:07:59 +04:00
zfree ( ( char * * ) & snode - > s ) ;
2013-01-25 04:59:59 +04:00
free ( snode ) ;
2009-07-01 02:01:20 +04:00
}
2012-07-31 08:31:33 +04:00
static
void strlist__node_delete ( struct rblist * rblist , struct rb_node * rb_node )
2009-07-01 02:01:20 +04:00
{
2012-07-31 08:31:33 +04:00
struct strlist * slist = container_of ( rblist , struct strlist , rblist ) ;
struct str_node * snode = container_of ( rb_node , struct str_node , rb_node ) ;
2009-07-01 02:01:20 +04:00
2012-07-31 08:31:33 +04:00
str_node__delete ( snode , slist - > dupstr ) ;
}
2009-07-01 02:01:20 +04:00
2012-07-31 08:31:33 +04:00
static int strlist__node_cmp ( struct rb_node * rb_node , const void * entry )
{
const char * str = entry ;
struct str_node * snode = container_of ( rb_node , struct str_node , rb_node ) ;
return strcmp ( snode - > s , str ) ;
}
2009-07-01 02:01:20 +04:00
2013-01-25 04:59:59 +04:00
int strlist__add ( struct strlist * slist , const char * new_entry )
2012-07-31 08:31:33 +04:00
{
2013-01-25 04:59:59 +04:00
return rblist__add_node ( & slist - > rblist , new_entry ) ;
2009-07-01 02:01:20 +04:00
}
2013-01-25 04:59:59 +04:00
int strlist__load ( struct strlist * slist , const char * filename )
2009-07-01 02:01:20 +04:00
{
char entry [ 1024 ] ;
int err ;
FILE * fp = fopen ( filename , " r " ) ;
if ( fp = = NULL )
return errno ;
while ( fgets ( entry , sizeof ( entry ) , fp ) ! = NULL ) {
const size_t len = strlen ( entry ) ;
if ( len = = 0 )
continue ;
entry [ len - 1 ] = ' \0 ' ;
2013-01-25 04:59:59 +04:00
err = strlist__add ( slist , entry ) ;
2009-07-01 02:01:20 +04:00
if ( err ! = 0 )
goto out ;
}
err = 0 ;
out :
fclose ( fp ) ;
return err ;
}
2012-07-31 08:31:33 +04:00
void strlist__remove ( struct strlist * slist , struct str_node * snode )
2009-07-01 02:01:20 +04:00
{
2012-08-29 10:00:07 +04:00
rblist__remove_node ( & slist - > rblist , & snode - > rb_node ) ;
2009-07-01 02:01:20 +04:00
}
2012-07-31 08:31:33 +04:00
struct str_node * strlist__find ( struct strlist * slist , const char * entry )
2009-07-01 02:01:20 +04:00
{
2012-07-31 08:31:33 +04:00
struct str_node * snode = NULL ;
struct rb_node * rb_node = rblist__find ( & slist - > rblist , entry ) ;
2009-07-01 02:01:20 +04:00
2012-07-31 08:31:33 +04:00
if ( rb_node )
snode = container_of ( rb_node , struct str_node , rb_node ) ;
return snode ;
2009-07-01 02:01:20 +04:00
}
2013-01-25 04:59:59 +04:00
static int strlist__parse_list_entry ( struct strlist * slist , const char * s )
2009-07-01 02:01:20 +04:00
{
if ( strncmp ( s , " file:// " , 7 ) = = 0 )
2013-01-25 04:59:59 +04:00
return strlist__load ( slist , s + 7 ) ;
2009-07-01 02:01:20 +04:00
2013-01-25 04:59:59 +04:00
return strlist__add ( slist , s ) ;
2009-07-01 02:01:20 +04:00
}
2013-01-25 04:59:59 +04:00
int strlist__parse_list ( struct strlist * slist , const char * s )
2009-07-01 02:01:20 +04:00
{
char * sep ;
int err ;
while ( ( sep = strchr ( s , ' , ' ) ) ! = NULL ) {
* sep = ' \0 ' ;
2013-01-25 04:59:59 +04:00
err = strlist__parse_list_entry ( slist , s ) ;
2009-07-01 02:01:20 +04:00
* sep = ' , ' ;
if ( err ! = 0 )
return err ;
s = sep + 1 ;
}
2013-01-25 04:59:59 +04:00
return * s ? strlist__parse_list_entry ( slist , s ) : 0 ;
2009-07-01 02:01:20 +04:00
}
2013-01-25 04:59:59 +04:00
struct strlist * strlist__new ( bool dupstr , const char * list )
2009-07-01 02:01:20 +04:00
{
2013-01-25 04:59:59 +04:00
struct strlist * slist = malloc ( sizeof ( * slist ) ) ;
2009-07-01 02:01:20 +04:00
2013-01-25 04:59:59 +04:00
if ( slist ! = NULL ) {
rblist__init ( & slist - > rblist ) ;
slist - > rblist . node_cmp = strlist__node_cmp ;
slist - > rblist . node_new = strlist__node_new ;
slist - > rblist . node_delete = strlist__node_delete ;
2012-07-31 08:31:33 +04:00
2013-01-25 04:59:59 +04:00
slist - > dupstr = dupstr ;
2013-03-12 13:02:17 +04:00
if ( list & & strlist__parse_list ( slist , list ) ! = 0 )
2009-07-01 02:01:20 +04:00
goto out_error ;
}
2013-01-25 04:59:59 +04:00
return slist ;
2009-07-01 02:01:20 +04:00
out_error :
2013-01-25 04:59:59 +04:00
free ( slist ) ;
2009-07-01 02:01:20 +04:00
return NULL ;
}
2013-01-25 04:59:59 +04:00
void strlist__delete ( struct strlist * slist )
2009-07-01 02:01:20 +04:00
{
2013-01-25 04:59:59 +04:00
if ( slist ! = NULL )
rblist__delete ( & slist - > rblist ) ;
2009-07-01 02:01:20 +04:00
}
2009-07-11 19:18:34 +04:00
2012-07-31 08:31:33 +04:00
struct str_node * strlist__entry ( const struct strlist * slist , unsigned int idx )
2009-07-11 19:18:34 +04:00
{
2012-07-31 08:31:33 +04:00
struct str_node * snode = NULL ;
struct rb_node * rb_node ;
2009-07-11 19:18:34 +04:00
2012-07-31 08:31:33 +04:00
rb_node = rblist__entry ( & slist - > rblist , idx ) ;
if ( rb_node )
snode = container_of ( rb_node , struct str_node , rb_node ) ;
2009-07-11 19:18:34 +04:00
2012-07-31 08:31:33 +04:00
return snode ;
2009-07-11 19:18:34 +04:00
}