Radix cross Linux package tools

Package Tools – is a set of utilities to create, install, and update RcL packages

3 Commits   0 Branches   2 Tags
11c606a6 (kx 2023-04-11 01:18:34 +0300   1) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   2) /**********************************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300   3) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   4)   Copyright 2019 Andrey V.Kosteltsev
11c606a6 (kx 2023-04-11 01:18:34 +0300   5) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   6)   Licensed under the Radix.pro License, Version 1.0 (the "License");
11c606a6 (kx 2023-04-11 01:18:34 +0300   7)   you may not use this file  except  in compliance with the License.
11c606a6 (kx 2023-04-11 01:18:34 +0300   8)   You may obtain a copy of the License at
11c606a6 (kx 2023-04-11 01:18:34 +0300   9) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  10)      https://radix.pro/licenses/LICENSE-1.0-en_US.txt
11c606a6 (kx 2023-04-11 01:18:34 +0300  11) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  12)   Unless required by applicable law or agreed to in writing, software
11c606a6 (kx 2023-04-11 01:18:34 +0300  13)   distributed under the License is distributed on an "AS IS" BASIS,
11c606a6 (kx 2023-04-11 01:18:34 +0300  14)   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
11c606a6 (kx 2023-04-11 01:18:34 +0300  15)   implied.
11c606a6 (kx 2023-04-11 01:18:34 +0300  16) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  17)  **********************************************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300  18) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  19) #include <config.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300  20) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  21) #include <stdlib.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300  22) #include <stdio.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300  23) #include <string.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300  24) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  25) #include <msglog.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300  26) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  27) #include <dlist.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300  28) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  29) struct dlist *__dlist_alloc( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  30) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  31)   struct dlist *list = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  32) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  33)   list = (struct dlist *)malloc( sizeof( struct dlist ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  34)   if( !list ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  35) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  36)   bzero( (void *)list, sizeof( struct dlist ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  37) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  38)   return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300  39) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  40) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  41) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  42) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  43) struct dlist *dlist_first( struct dlist *list )
11c606a6 (kx 2023-04-11 01:18:34 +0300  44) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  45)   while( list && dlist_prev( list ) ) list = dlist_prev( list );
11c606a6 (kx 2023-04-11 01:18:34 +0300  46) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  47)   return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300  48) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  49) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  50) struct dlist *dlist_last( struct dlist *list )
11c606a6 (kx 2023-04-11 01:18:34 +0300  51) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  52)   while( list && dlist_next( list ) ) list = dlist_next( list );
11c606a6 (kx 2023-04-11 01:18:34 +0300  53) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  54)   return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300  55) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  56) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  57) int dlist_length( struct dlist *list )
11c606a6 (kx 2023-04-11 01:18:34 +0300  58) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  59)   int n = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  60) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  61)   while( list )
11c606a6 (kx 2023-04-11 01:18:34 +0300  62)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  63)     list = dlist_next( list );
11c606a6 (kx 2023-04-11 01:18:34 +0300  64)     ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300  65)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  66) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  67)   return n;
11c606a6 (kx 2023-04-11 01:18:34 +0300  68) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  69) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  70) struct dlist *dlist_nth( struct dlist *list, int n )
11c606a6 (kx 2023-04-11 01:18:34 +0300  71) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  72)   while( list && (n-- > 0) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  73)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  74)     list = dlist_next( list );
11c606a6 (kx 2023-04-11 01:18:34 +0300  75)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  76) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  77)   return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300  78) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  79) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  80) void *dlist_nth_data( struct dlist *list, int n )
11c606a6 (kx 2023-04-11 01:18:34 +0300  81) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  82)   while( list && (n-- > 0) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  83)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  84)     list = dlist_next( list );
11c606a6 (kx 2023-04-11 01:18:34 +0300  85)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  86) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  87)   return list ? list->data : NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  88) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  89) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  90) int dlist_position( struct dlist *list, struct dlist *link )
11c606a6 (kx 2023-04-11 01:18:34 +0300  91) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  92)   int n = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  93) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  94)   while( list )
11c606a6 (kx 2023-04-11 01:18:34 +0300  95)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  96)     if( list == link ) return n;
11c606a6 (kx 2023-04-11 01:18:34 +0300  97)     ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300  98)     list = dlist_next( list );
11c606a6 (kx 2023-04-11 01:18:34 +0300  99)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 100) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 101)   return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 102) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 103) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 104) int dlist_index( struct dlist *list, const void *data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 105) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 106)   int n = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 107) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 108)   while( list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 109)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 110)     if( list->data == data ) return n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 111)     ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 112)     list = dlist_next( list );
11c606a6 (kx 2023-04-11 01:18:34 +0300 113)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 114) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 115)   return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 116) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 117) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 118) struct dlist *dlist_find( struct dlist *list, const void *data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 119) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 120)   while( list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 121)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 122)     if( list->data == data ) { break; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 123)     list = dlist_next( list );
11c606a6 (kx 2023-04-11 01:18:34 +0300 124)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 125) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 126)   return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 127) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 128) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 129) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 130) struct dlist *dlist_find_data( struct dlist *list, DLCMPF cmp_func, const void *data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 131) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 132)   if( !list || !cmp_func ) return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 133) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 134)   while( list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 135)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 136)     if( ! cmp_func( list->data, data ) ) { return list; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 137)     list = dlist_next( list );
11c606a6 (kx 2023-04-11 01:18:34 +0300 138)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 139) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 140)   return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 141) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 142) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 143) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 144) struct dlist *dlist_append( struct dlist *list, void *data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 145) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 146)   struct dlist *node = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 147)   struct dlist *last = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 148) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 149)   node = __dlist_alloc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 150)   node->data = data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 151) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 152)   if( list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 153)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 154)     last = dlist_last( list );
11c606a6 (kx 2023-04-11 01:18:34 +0300 155) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 156)     dlist_next( last ) = node;
11c606a6 (kx 2023-04-11 01:18:34 +0300 157)     dlist_prev( node ) = last;
11c606a6 (kx 2023-04-11 01:18:34 +0300 158) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 159)     return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 160)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 161) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 162)   return node;
11c606a6 (kx 2023-04-11 01:18:34 +0300 163) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 164) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 165) struct dlist *dlist_prepend( struct dlist *list, void *data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 166) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 167)   struct dlist *node  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 168)   struct dlist *first = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 169) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 170)   node = __dlist_alloc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 171)   node->data = data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 172) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 173)   if( list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 174)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 175)     first = dlist_first( list );
11c606a6 (kx 2023-04-11 01:18:34 +0300 176) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 177)     dlist_prev( first ) = node;
11c606a6 (kx 2023-04-11 01:18:34 +0300 178)     dlist_next( node )  = first;
11c606a6 (kx 2023-04-11 01:18:34 +0300 179) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 180)     return node;
11c606a6 (kx 2023-04-11 01:18:34 +0300 181)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 182) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 183)   return node;
11c606a6 (kx 2023-04-11 01:18:34 +0300 184) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 185) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 186) struct dlist *dlist_insert( struct dlist *list, void *data, int position )
11c606a6 (kx 2023-04-11 01:18:34 +0300 187) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 188)   struct dlist *node  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 189)   struct dlist *ptr   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 190) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 191)   if( position  < 0 ) { return dlist_append( list, data );  }
11c606a6 (kx 2023-04-11 01:18:34 +0300 192)   if( position == 0 ) { return dlist_prepend( list, data ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 193) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 194)   ptr = dlist_nth( list, position );
11c606a6 (kx 2023-04-11 01:18:34 +0300 195)   if( !ptr ) { return dlist_append( list, data ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 196) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 197)   node = __dlist_alloc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 198)   node->data = data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 199) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 200)   node->prev = ptr->prev;
11c606a6 (kx 2023-04-11 01:18:34 +0300 201)   ptr->prev->next = node;
11c606a6 (kx 2023-04-11 01:18:34 +0300 202)   node->next = ptr;
11c606a6 (kx 2023-04-11 01:18:34 +0300 203)   ptr->prev = node;
11c606a6 (kx 2023-04-11 01:18:34 +0300 204) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 205)   return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 206) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 207) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 208) struct dlist *dlist_insert_sorted( struct dlist *list, DLCMPF cmp_func, void *data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 209) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 210)   struct dlist *node  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 211)   struct dlist *ptr   = list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 212)   int cmp;
11c606a6 (kx 2023-04-11 01:18:34 +0300 213) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 214)   if( !cmp_func ) return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 215) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 216)   if( !list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 217)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 218)     node = __dlist_alloc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 219)     node->data = data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 220)     return node;
11c606a6 (kx 2023-04-11 01:18:34 +0300 221)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 222) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 223)   cmp = cmp_func( data, ptr->data );
11c606a6 (kx 2023-04-11 01:18:34 +0300 224) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 225)   while( (ptr->next) && (cmp > 0) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 226)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 227)     ptr = ptr->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 228)     cmp = cmp_func( data, ptr->data );
11c606a6 (kx 2023-04-11 01:18:34 +0300 229)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 230) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 231)   node = __dlist_alloc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 232)   node->data = data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 233) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 234)   if( (!ptr->next) && (cmp > 0) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 235)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 236)     ptr->next = node;
11c606a6 (kx 2023-04-11 01:18:34 +0300 237)     node->prev = ptr;
11c606a6 (kx 2023-04-11 01:18:34 +0300 238)     return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 239)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 240) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 241)   if( ptr->prev )
11c606a6 (kx 2023-04-11 01:18:34 +0300 242)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 243)     ptr->prev->next = node;
11c606a6 (kx 2023-04-11 01:18:34 +0300 244)     node->prev = ptr->prev;
11c606a6 (kx 2023-04-11 01:18:34 +0300 245)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 246)   node->next = ptr;
11c606a6 (kx 2023-04-11 01:18:34 +0300 247)   ptr->prev = node;
11c606a6 (kx 2023-04-11 01:18:34 +0300 248) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 249)   if( ptr == list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 250)     return node;
11c606a6 (kx 2023-04-11 01:18:34 +0300 251)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 252)     return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 253) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 254) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 255) struct dlist *dlist_insert_sorted_with_data( struct dlist *list, DLCMPDF cmp_func, void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 256) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 257)   struct dlist *node  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 258)   struct dlist *ptr   = list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 259)   int cmp;
11c606a6 (kx 2023-04-11 01:18:34 +0300 260) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 261)   if( !cmp_func ) return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 262) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 263)   if( !list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 264)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 265)     node = __dlist_alloc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 266)     node->data = data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 267)     return node;
11c606a6 (kx 2023-04-11 01:18:34 +0300 268)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 269) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 270)   cmp = cmp_func( data, ptr->data, user_data );
11c606a6 (kx 2023-04-11 01:18:34 +0300 271) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 272)   while( (ptr->next) && (cmp > 0) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 273)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 274)     ptr = ptr->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 275)     cmp = cmp_func( data, ptr->data, user_data );
11c606a6 (kx 2023-04-11 01:18:34 +0300 276)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 277) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 278)   node = __dlist_alloc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 279)   node->data = data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 280) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 281)   if( (!ptr->next) && (cmp > 0) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 282)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 283)     ptr->next = node;
11c606a6 (kx 2023-04-11 01:18:34 +0300 284)     node->prev = ptr;
11c606a6 (kx 2023-04-11 01:18:34 +0300 285)     return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 286)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 287) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 288)   if( ptr->prev )
11c606a6 (kx 2023-04-11 01:18:34 +0300 289)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 290)     ptr->prev->next = node;
11c606a6 (kx 2023-04-11 01:18:34 +0300 291)     node->prev = ptr->prev;
11c606a6 (kx 2023-04-11 01:18:34 +0300 292)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 293)   node->next = ptr;
11c606a6 (kx 2023-04-11 01:18:34 +0300 294)   ptr->prev = node;
11c606a6 (kx 2023-04-11 01:18:34 +0300 295) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 296)   if( ptr == list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 297)     return node;
11c606a6 (kx 2023-04-11 01:18:34 +0300 298)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 299)     return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 300) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 301) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 302) struct dlist *dlist_concat( struct dlist *list1, struct dlist *list2 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 303) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 304)   struct dlist *ptr   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 305) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 306)   if( list2 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 307)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 308)     ptr = dlist_last( list1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 309)     if( ptr )
11c606a6 (kx 2023-04-11 01:18:34 +0300 310)       ptr->next = list2;
11c606a6 (kx 2023-04-11 01:18:34 +0300 311)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 312)       list1 = list2;
11c606a6 (kx 2023-04-11 01:18:34 +0300 313) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 314)     list2->prev = ptr;
11c606a6 (kx 2023-04-11 01:18:34 +0300 315)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 316) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 317)   return list1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 318) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 319) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 320) struct dlist *dlist_insert_list( struct dlist *list1, struct dlist *list2, int position )
11c606a6 (kx 2023-04-11 01:18:34 +0300 321) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 322)   struct dlist *last  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 323)   struct dlist *ptr   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 324) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 325)   if( position  < 0 ) { return dlist_concat( list1, list2 ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 326)   if( position == 0 ) { return dlist_concat( list2, list1 ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 327) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 328)   ptr = dlist_nth( list1, position );
11c606a6 (kx 2023-04-11 01:18:34 +0300 329)   if( !ptr ) { return dlist_concat( list1, list2 ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 330) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 331)   last = dlist_last( list2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 332)   if( last )
11c606a6 (kx 2023-04-11 01:18:34 +0300 333)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 334)     list2->prev = ptr->prev;
11c606a6 (kx 2023-04-11 01:18:34 +0300 335)     ptr->prev->next = list2;
11c606a6 (kx 2023-04-11 01:18:34 +0300 336)     last->next = ptr;
11c606a6 (kx 2023-04-11 01:18:34 +0300 337)     ptr->prev = last;
11c606a6 (kx 2023-04-11 01:18:34 +0300 338)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 339) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 340)   return list1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 341) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 342) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 343) struct dlist *__dlist_remove_link( struct dlist *list, struct dlist *link )
11c606a6 (kx 2023-04-11 01:18:34 +0300 344) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 345)   if( link == NULL ) return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 346) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 347)   if( link->prev )
11c606a6 (kx 2023-04-11 01:18:34 +0300 348)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 349)     if( link->prev->next == link )
11c606a6 (kx 2023-04-11 01:18:34 +0300 350)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 351)         link->prev->next = link->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 352)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 353)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 354)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 355)       WARNING( "Corrupted double-linked list detected" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 356)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 357)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 358)   if( link->next )
11c606a6 (kx 2023-04-11 01:18:34 +0300 359)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 360)     if( link->next->prev == link )
11c606a6 (kx 2023-04-11 01:18:34 +0300 361)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 362)       link->next->prev = link->prev;
11c606a6 (kx 2023-04-11 01:18:34 +0300 363)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 364)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 365)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 366)       WARNING( "Corrupted double-linked list detected" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 367)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 368)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 369) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 370)   if( link == list ) list = list->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 371) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 372)   link->next = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 373)   link->prev = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 374) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 375)   return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 376) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 377) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 378) struct dlist *dlist_remove( struct dlist *list, const void *data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 379) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 380)   struct dlist *ptr = list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 381) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 382)   while( ptr )
11c606a6 (kx 2023-04-11 01:18:34 +0300 383)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 384)     if( ptr->data != data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 385)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 386)       ptr = ptr->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 387)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 388)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 389)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 390)       list = __dlist_remove_link( list, ptr );
11c606a6 (kx 2023-04-11 01:18:34 +0300 391)       free( ptr );
11c606a6 (kx 2023-04-11 01:18:34 +0300 392) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 393)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 394)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 395)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 396) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 397)   return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 398) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 399) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 400) struct dlist *dlist_remove_all( struct dlist *list, const void *data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 401) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 402)   struct dlist *ptr = list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 403) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 404)   while( ptr )
11c606a6 (kx 2023-04-11 01:18:34 +0300 405)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 406)     if( ptr->data != data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 407)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 408)       ptr = ptr->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 409)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 410)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 411)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 412)       struct dlist *next = ptr->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 413) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 414)       if( ptr->prev )
11c606a6 (kx 2023-04-11 01:18:34 +0300 415)         ptr->prev->next = next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 416)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300 417)         list = next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 418) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 419)       if( next )
11c606a6 (kx 2023-04-11 01:18:34 +0300 420)         next->prev = ptr->prev;
11c606a6 (kx 2023-04-11 01:18:34 +0300 421) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 422)       free( ptr );
11c606a6 (kx 2023-04-11 01:18:34 +0300 423) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 424)       ptr = next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 425)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 426)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 427) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 428)   return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 429) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 430) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 431) struct dlist *dlist_remove_data( struct dlist *list, DLCMPF cmp_func, DLFUNC free_func, const void *data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 432) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 433)   struct dlist *ptr = list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 434) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 435)   if( !cmp_func ) return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 436) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 437)   while( ptr )
11c606a6 (kx 2023-04-11 01:18:34 +0300 438)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 439)     if( cmp_func( ptr->data, data ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 440)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 441)       ptr = ptr->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 442)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 443)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 444)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 445)       list = __dlist_remove_link( list, ptr );
11c606a6 (kx 2023-04-11 01:18:34 +0300 446)       if( free_func ) free_func( ptr->data, (void *)data ); /* free_func() can compare pointers */
11c606a6 (kx 2023-04-11 01:18:34 +0300 447)       free( ptr );
11c606a6 (kx 2023-04-11 01:18:34 +0300 448) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 449)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 450)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 451)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 452) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 453)   return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 454) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 455) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 456) struct dlist *dlist_remove_data_all( struct dlist *list, DLCMPF cmp_func, DLFUNC free_func, const void *data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 457) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 458)   struct dlist *ptr = list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 459) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 460)   if( !cmp_func ) return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 461) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 462)   while( ptr )
11c606a6 (kx 2023-04-11 01:18:34 +0300 463)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 464)     if( cmp_func( ptr->data, data ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 465)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 466)       ptr = ptr->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 467)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 468)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 469)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 470)       struct dlist *next = ptr->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 471) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 472)       if( ptr->prev )
11c606a6 (kx 2023-04-11 01:18:34 +0300 473)         ptr->prev->next = next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 474)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300 475)         list = next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 476) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 477)       if( next )
11c606a6 (kx 2023-04-11 01:18:34 +0300 478)         next->prev = ptr->prev;
11c606a6 (kx 2023-04-11 01:18:34 +0300 479) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 480)       if( free_func ) free_func( ptr->data, (void *)data ); /* free_func() can compare pointers */
11c606a6 (kx 2023-04-11 01:18:34 +0300 481)       free( ptr );
11c606a6 (kx 2023-04-11 01:18:34 +0300 482) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 483)       ptr = next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 484)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 485)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 486) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 487)   return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 488) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 489) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 490) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 491) struct dlist *dlist_copy( struct dlist *list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 492) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 493)   struct dlist *copy = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 494) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 495)   while( list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 496)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 497)     copy = dlist_append( copy, list->data );
11c606a6 (kx 2023-04-11 01:18:34 +0300 498)     list = dlist_next( list );
11c606a6 (kx 2023-04-11 01:18:34 +0300 499)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 500) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 501)   return copy;
11c606a6 (kx 2023-04-11 01:18:34 +0300 502) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 503) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 504) /* It simply switches the next and prev pointers of each element. */
11c606a6 (kx 2023-04-11 01:18:34 +0300 505) struct dlist *dlist_reverse( struct dlist *list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 506) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 507)   struct dlist *last = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 508) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 509)   while( list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 510)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 511)     last = list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 512)     list = last->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 513)     last->next = last->prev;
11c606a6 (kx 2023-04-11 01:18:34 +0300 514)     last->prev = list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 515)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 516) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 517)   return last;
11c606a6 (kx 2023-04-11 01:18:34 +0300 518) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 519) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 520) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 521) static struct dlist *__dlist_sort_merge( struct dlist *l1, struct dlist *l2, DLCMPF cmp_func )
11c606a6 (kx 2023-04-11 01:18:34 +0300 522) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 523)   struct dlist list, *l, *lprev;
11c606a6 (kx 2023-04-11 01:18:34 +0300 524)   int   cmp;
11c606a6 (kx 2023-04-11 01:18:34 +0300 525) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 526)   l = &list; 
11c606a6 (kx 2023-04-11 01:18:34 +0300 527)   lprev = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 528) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 529)   while( l1 && l2 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 530)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 531)     cmp = ((DLCMPF) cmp_func)( l1->data, l2->data );
11c606a6 (kx 2023-04-11 01:18:34 +0300 532) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 533)     if( cmp <= 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 534)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 535)       l->next = l1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 536)       l1 = l1->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 537)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 538)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 539)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 540)       l->next = l2;
11c606a6 (kx 2023-04-11 01:18:34 +0300 541)       l2 = l2->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 542)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 543)     l = l->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 544)     l->prev = lprev; 
11c606a6 (kx 2023-04-11 01:18:34 +0300 545)     lprev = l;
11c606a6 (kx 2023-04-11 01:18:34 +0300 546)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 547)   l->next = l1 ? l1 : l2;
11c606a6 (kx 2023-04-11 01:18:34 +0300 548)   l->next->prev = l;
11c606a6 (kx 2023-04-11 01:18:34 +0300 549) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 550)   return list.next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 551) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 552) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 553) static struct dlist *__dlist_sort_merge_with_data( struct dlist *l1, struct dlist *l2, DLCMPDF cmp_func, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 554) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 555)   struct dlist list, *l, *lprev;
11c606a6 (kx 2023-04-11 01:18:34 +0300 556)   int   cmp;
11c606a6 (kx 2023-04-11 01:18:34 +0300 557) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 558)   l = &list; 
11c606a6 (kx 2023-04-11 01:18:34 +0300 559)   lprev = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 560) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 561)   while( l1 && l2 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 562)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 563)     cmp = ((DLCMPDF) cmp_func)( l1->data, l2->data, user_data );
11c606a6 (kx 2023-04-11 01:18:34 +0300 564) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 565)     if( cmp <= 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 566)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 567)       l->next = l1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 568)       l1 = l1->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 569)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 570)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 571)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 572)       l->next = l2;
11c606a6 (kx 2023-04-11 01:18:34 +0300 573)       l2 = l2->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 574)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 575)     l = l->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 576)     l->prev = lprev; 
11c606a6 (kx 2023-04-11 01:18:34 +0300 577)     lprev = l;
11c606a6 (kx 2023-04-11 01:18:34 +0300 578)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 579)   l->next = l1 ? l1 : l2;
11c606a6 (kx 2023-04-11 01:18:34 +0300 580)   l->next->prev = l;
11c606a6 (kx 2023-04-11 01:18:34 +0300 581) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 582)   return list.next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 583) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 584) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 585) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 586) static struct dlist *__dlist_sort_real( struct dlist *list, DLCMPF cmp_func )
11c606a6 (kx 2023-04-11 01:18:34 +0300 587) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 588)   struct dlist *l1, *l2;
11c606a6 (kx 2023-04-11 01:18:34 +0300 589) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 590)   if( !list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 591)     return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 592)   if( !list->next )
11c606a6 (kx 2023-04-11 01:18:34 +0300 593)     return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 594) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 595)   l1 = list; 
11c606a6 (kx 2023-04-11 01:18:34 +0300 596)   l2 = list->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 597) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 598)   while( (l2 = l2->next) != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 599)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 600)     if( (l2 = l2->next) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 601)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 602)     l1 = l1->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 603)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 604)   l2 = l1->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 605)   l1->next = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 606) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 607)   return __dlist_sort_merge( __dlist_sort_real( list, cmp_func ),
11c606a6 (kx 2023-04-11 01:18:34 +0300 608)                              __dlist_sort_real( l2, cmp_func ),
11c606a6 (kx 2023-04-11 01:18:34 +0300 609)                              cmp_func );
11c606a6 (kx 2023-04-11 01:18:34 +0300 610) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 611) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 612) static struct dlist *__dlist_sort_real_with_data( struct dlist *list, DLCMPDF cmp_func, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 613) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 614)   struct dlist *l1, *l2;
11c606a6 (kx 2023-04-11 01:18:34 +0300 615) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 616)   if( !list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 617)     return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 618)   if( !list->next )
11c606a6 (kx 2023-04-11 01:18:34 +0300 619)     return list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 620) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 621)   l1 = list; 
11c606a6 (kx 2023-04-11 01:18:34 +0300 622)   l2 = list->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 623) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 624)   while( (l2 = l2->next) != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 625)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 626)     if( (l2 = l2->next) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 627)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 628)     l1 = l1->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 629)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 630)   l2 = l1->next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 631)   l1->next = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 632) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 633)   return __dlist_sort_merge_with_data( __dlist_sort_real_with_data( list, cmp_func, user_data ),
11c606a6 (kx 2023-04-11 01:18:34 +0300 634)                                        __dlist_sort_real_with_data( l2, cmp_func, user_data ),
11c606a6 (kx 2023-04-11 01:18:34 +0300 635)                                        cmp_func,
11c606a6 (kx 2023-04-11 01:18:34 +0300 636)                                        user_data );
11c606a6 (kx 2023-04-11 01:18:34 +0300 637) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 638) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 639) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 640) struct dlist *dlist_sort( struct dlist *list, DLCMPF cmp_func )
11c606a6 (kx 2023-04-11 01:18:34 +0300 641) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 642)   return __dlist_sort_real( list, cmp_func );
11c606a6 (kx 2023-04-11 01:18:34 +0300 643) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 644) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 645) struct dlist *dlist_sort_with_data( struct dlist *list, DLCMPDF cmp_func, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 646) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 647)   return __dlist_sort_real_with_data( list, cmp_func, user_data );
11c606a6 (kx 2023-04-11 01:18:34 +0300 648) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 649) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 650) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 651) void dlist_foreach( struct dlist *list, DLFUNC func, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 652) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 653)   struct dlist *next = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 654) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 655)   while( list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 656)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 657)     next = dlist_next( list );
11c606a6 (kx 2023-04-11 01:18:34 +0300 658)     if( func ) { func( list->data, user_data ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 659)     list = next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 660)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 661) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 662) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 663) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 664) void __dlist_free( struct dlist *list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 665) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 666)   struct dlist *next = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 667) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 668)   while( list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 669)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 670)     next = dlist_next( list );
11c606a6 (kx 2023-04-11 01:18:34 +0300 671)     free( list ); list = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 672)     list = next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 673)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 674) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 675) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 676) void dlist_free( struct dlist *list, DLFUNC free_func )
11c606a6 (kx 2023-04-11 01:18:34 +0300 677) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 678)   dlist_foreach( list, free_func, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 679)   __dlist_free( list );
11c606a6 (kx 2023-04-11 01:18:34 +0300 680) }