2019-05-30 02:57:21 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2012-07-31 08:31:34 +04:00
/*
* Based on intlist . c by :
* ( c ) 2009 Arnaldo Carvalho de Melo < acme @ redhat . com >
*/
# include <errno.h>
# include <stdlib.h>
# include <linux/compiler.h>
# include "intlist.h"
2012-09-11 02:15:03 +04:00
static struct rb_node * intlist__node_new ( struct rblist * rblist __maybe_unused ,
2012-07-31 08:31:34 +04:00
const void * entry )
{
int i = ( int ) ( ( long ) entry ) ;
struct rb_node * rc = NULL ;
struct int_node * node = malloc ( sizeof ( * node ) ) ;
if ( node ! = NULL ) {
node - > i = i ;
2013-09-28 23:13:02 +04:00
node - > priv = NULL ;
2012-07-31 08:31:34 +04:00
rc = & node - > rb_node ;
}
return rc ;
}
static void int_node__delete ( struct int_node * ilist )
{
free ( ilist ) ;
}
2012-09-11 02:15:03 +04:00
static void intlist__node_delete ( struct rblist * rblist __maybe_unused ,
2012-07-31 08:31:34 +04:00
struct rb_node * rb_node )
{
struct int_node * node = container_of ( rb_node , struct int_node , rb_node ) ;
int_node__delete ( node ) ;
}
static int intlist__node_cmp ( struct rb_node * rb_node , const void * entry )
{
int i = ( int ) ( ( long ) entry ) ;
struct int_node * node = container_of ( rb_node , struct int_node , rb_node ) ;
return node - > i - i ;
}
int intlist__add ( struct intlist * ilist , int i )
{
return rblist__add_node ( & ilist - > rblist , ( void * ) ( ( long ) i ) ) ;
}
2012-08-31 10:58:47 +04:00
void intlist__remove ( struct intlist * ilist , struct int_node * node )
2012-07-31 08:31:34 +04:00
{
2012-08-31 10:58:47 +04:00
rblist__remove_node ( & ilist - > rblist , & node - > rb_node ) ;
2012-07-31 08:31:34 +04:00
}
2013-10-09 07:26:52 +04:00
static struct int_node * __intlist__findnew ( struct intlist * ilist ,
int i , bool create )
2012-07-31 08:31:34 +04:00
{
2013-10-09 07:26:52 +04:00
struct int_node * node = NULL ;
2013-01-24 23:10:42 +04:00
struct rb_node * rb_node ;
if ( ilist = = NULL )
return NULL ;
2012-07-31 08:31:34 +04:00
2013-10-09 07:26:52 +04:00
if ( create )
rb_node = rblist__findnew ( & ilist - > rblist , ( void * ) ( ( long ) i ) ) ;
else
rb_node = rblist__find ( & ilist - > rblist , ( void * ) ( ( long ) i ) ) ;
2012-07-31 08:31:34 +04:00
if ( rb_node )
node = container_of ( rb_node , struct int_node , rb_node ) ;
return node ;
}
2013-10-09 07:26:52 +04:00
struct int_node * intlist__find ( struct intlist * ilist , int i )
{
return __intlist__findnew ( ilist , i , false ) ;
}
struct int_node * intlist__findnew ( struct intlist * ilist , int i )
{
return __intlist__findnew ( ilist , i , true ) ;
}
2013-01-24 23:17:27 +04:00
static int intlist__parse_list ( struct intlist * ilist , const char * s )
{
char * sep ;
int err ;
do {
long value = strtol ( s , & sep , 10 ) ;
err = - EINVAL ;
if ( * sep ! = ' , ' & & * sep ! = ' \0 ' )
break ;
err = intlist__add ( ilist , value ) ;
if ( err )
break ;
s = sep + 1 ;
} while ( * sep ! = ' \0 ' ) ;
return err ;
}
struct intlist * intlist__new ( const char * slist )
2012-07-31 08:31:34 +04:00
{
struct intlist * ilist = malloc ( sizeof ( * ilist ) ) ;
if ( ilist ! = NULL ) {
rblist__init ( & ilist - > rblist ) ;
ilist - > rblist . node_cmp = intlist__node_cmp ;
ilist - > rblist . node_new = intlist__node_new ;
ilist - > rblist . node_delete = intlist__node_delete ;
2013-01-24 23:17:27 +04:00
if ( slist & & intlist__parse_list ( ilist , slist ) )
goto out_delete ;
2012-07-31 08:31:34 +04:00
}
return ilist ;
2013-01-24 23:17:27 +04:00
out_delete :
intlist__delete ( ilist ) ;
return NULL ;
2012-07-31 08:31:34 +04:00
}
void intlist__delete ( struct intlist * ilist )
{
if ( ilist ! = NULL )
rblist__delete ( & ilist - > rblist ) ;
}
struct int_node * intlist__entry ( const struct intlist * ilist , unsigned int idx )
{
struct int_node * node = NULL ;
struct rb_node * rb_node ;
rb_node = rblist__entry ( & ilist - > rblist , idx ) ;
if ( rb_node )
node = container_of ( rb_node , struct int_node , rb_node ) ;
return node ;
}