]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/tools/build/src/engine/lists.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / tools / build / src / engine / lists.cpp
CommitLineData
7c673cae
FG
1/*
2 * Copyright 1993, 1995 Christopher Seiwald.
3 *
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
6
7/*
8 * lists.c - maintain lists of objects
9 */
10
11#include "jam.h"
12#include "lists.h"
1e59de90 13#include "mem.h"
7c673cae 14#include "output.h"
1e59de90 15#include "startup.h"
7c673cae
FG
16
17#include <assert.h>
18
1e59de90 19static int32_t get_bucket( int32_t size )
7c673cae 20{
1e59de90
TL
21 int32_t bucket = 0;
22 while ( size > ( int32_t(1) << bucket ) ) ++bucket;
7c673cae
FG
23 return bucket;
24}
25
1e59de90 26static LIST * list_alloc( int32_t size )
7c673cae 27{
1e59de90
TL
28 int32_t bucket = get_bucket( size );
29 return b2::jam::ctor_ptr<LIST>( BJAM_CALLOC(
30 1, sizeof( LIST ) + ( size_t( 1 ) << bucket ) * sizeof( OBJECT * ) ) );
7c673cae
FG
31}
32
33static void list_dealloc( LIST * l )
34{
1e59de90 35 int32_t size = list_length( l );
7c673cae
FG
36 LIST * node = l;
37
38 if ( size == 0 ) return;
39
1e59de90 40 b2::jam::free_ptr( node );
7c673cae
FG
41}
42
43/*
44 * list_append() - append a list onto another one, returning total
45 */
46
47LIST * list_append( LIST * l, LIST * nl )
48{
49 if ( list_empty( l ) )
50 return nl;
51 if ( !list_empty( nl ) )
52 {
1e59de90
TL
53 int32_t l_size = list_length( l );
54 int32_t nl_size = list_length( nl );
55 int32_t size = l_size + nl_size;
56 int32_t bucket = get_bucket( size );
7c673cae
FG
57
58 /* Do we need to reallocate? */
1e59de90 59 if ( l_size <= ( int32_t(1) << ( bucket - 1 ) ) )
7c673cae
FG
60 {
61 LIST * result = list_alloc( size );
62 memcpy( list_begin( result ), list_begin( l ), l_size * sizeof(
63 OBJECT * ) );
64 list_dealloc( l );
65 l = result;
66 }
67
68 l->impl.size = size;
69 memcpy( list_begin( l ) + l_size, list_begin( nl ), nl_size * sizeof(
70 OBJECT * ) );
71 list_dealloc( nl );
72 }
73 return l;
74}
75
76LISTITER list_begin( LIST * l )
77{
78 return l ? (LISTITER)( (char *)l + sizeof( LIST ) ) : 0;
79}
80
81LISTITER list_end( LIST * l )
82{
83 return l ? list_begin( l ) + l->impl.size : 0;
84}
85
86LIST * list_new( OBJECT * value )
87{
88 LIST * const head = list_alloc( 1 ) ;
89 head->impl.size = 1;
90 list_begin( head )[ 0 ] = value;
91 return head;
92}
93
94/*
95 * list_push_back() - tack a string onto the end of a list of strings
96 */
97
98LIST * list_push_back( LIST * head, OBJECT * value )
99{
1e59de90 100 int32_t size = list_length( head );
7c673cae
FG
101
102 if ( DEBUG_LISTS )
103 out_printf( "list > %s <\n", object_str( value ) );
104
105 /* If the size is a power of 2, reallocate. */
106 if ( size == 0 )
107 {
108 head = list_alloc( 1 );
109 }
110 else if ( ( ( size - 1 ) & size ) == 0 )
111 {
112 LIST * l = list_alloc( size + 1 );
113 memcpy( l, head, sizeof( LIST ) + size * sizeof( OBJECT * ) );
114 list_dealloc( head );
115 head = l;
116 }
117
118 list_begin( head )[ size ] = value;
119 head->impl.size = size + 1;
120
121 return head;
122}
123
124
125/*
126 * list_copy() - copy a whole list of strings (nl) onto end of another (l).
127 */
128
129LIST * list_copy( LIST * l )
130{
1e59de90
TL
131 int32_t size = list_length( l );
132 int32_t i;
7c673cae
FG
133 LIST * result;
134
135 if ( size == 0 ) return L0;
136
137 result = list_alloc( size );
138 result->impl.size = size;
139 for ( i = 0; i < size; ++i )
140 list_begin( result )[ i ] = object_copy( list_begin( l )[ i ] );
141 return result;
142}
143
144
145LIST * list_copy_range( LIST * l, LISTITER first, LISTITER last )
146{
147 if ( first == last )
148 return L0;
149 else
150 {
1e59de90 151 int32_t size = int32_t( last - first );
7c673cae
FG
152 LIST * result = list_alloc( size );
153 LISTITER dest = list_begin( result );
154 result->impl.size = size;
155 for ( ; first != last; ++first, ++dest )
156 *dest = object_copy( *first );
157 return result;
158 }
159}
160
161
162/*
163 * list_sublist() - copy a subset of a list of strings.
164 */
165
1e59de90 166LIST * list_sublist( LIST * l, int32_t start, int32_t count )
7c673cae 167{
1e59de90
TL
168 int32_t end = start + count;
169 int32_t size = list_length( l );
7c673cae
FG
170 if ( start >= size ) return L0;
171 if ( end > size ) end = size;
172 return list_copy_range( l, list_begin( l ) + start, list_begin( l ) + end );
173}
174
175
1e59de90 176static int32_t str_ptr_compare( void const * va, void const * vb )
7c673cae
FG
177{
178 OBJECT * a = *( (OBJECT * *)va );
179 OBJECT * b = *( (OBJECT * *)vb );
180 return strcmp( object_str( a ), object_str( b ) );
181}
182
183
184LIST * list_sort( LIST * l )
185{
1e59de90 186 int32_t len;
7c673cae
FG
187 LIST * result;
188
189 if ( !l )
190 return L0;
191
192 len = list_length( l );
193 result = list_copy( l );
194
195 qsort( list_begin( result ), len, sizeof( OBJECT * ), str_ptr_compare );
196
197 return result;
198}
199
200
201/*
202 * list_free() - free a list of strings
203 */
204
205void list_free( LIST * head )
206{
207 if ( !list_empty( head ) )
208 {
209 LISTITER iter = list_begin( head );
210 LISTITER const end = list_end( head );
211 for ( ; iter != end; iter = list_next( iter ) )
212 object_free( list_item( iter ) );
213 list_dealloc( head );
214 }
215}
216
217
218/*
219 * list_pop_front() - remove the front element from a list of strings
220 */
221
222LIST * list_pop_front( LIST * l )
223{
1e59de90 224 int32_t size = list_length( l );
7c673cae
FG
225 assert( size );
226 --size;
227 object_free( list_front( l ) );
228
229 if ( size == 0 )
230 {
231 list_dealloc( l );
232 return L0;
233 }
234
235 if ( ( ( size - 1 ) & size ) == 0 )
236 {
237 LIST * const nl = list_alloc( size );
238 nl->impl.size = size;
239 memcpy( list_begin( nl ), list_begin( l ) + 1, size * sizeof( OBJECT * )
240 );
241 list_dealloc( l );
242 return nl;
243 }
244
245 l->impl.size = size;
246 memmove( list_begin( l ), list_begin( l ) + 1, size * sizeof( OBJECT * ) );
247 return l;
248}
249
250LIST * list_reverse( LIST * l )
251{
1e59de90 252 int32_t size = list_length( l );
7c673cae
FG
253 if ( size == 0 ) return L0;
254 {
255 LIST * const result = list_alloc( size );
1e59de90 256 int32_t i;
7c673cae
FG
257 result->impl.size = size;
258 for ( i = 0; i < size; ++i )
259 list_begin( result )[ i ] = object_copy( list_begin( l )[ size - i -
260 1 ] );
261 return result;
262 }
263}
264
1e59de90 265int32_t list_cmp( LIST * t, LIST * s )
7c673cae 266{
1e59de90 267 int32_t status = 0;
7c673cae
FG
268 LISTITER t_it = list_begin( t );
269 LISTITER const t_end = list_end( t );
270 LISTITER s_it = list_begin( s );
271 LISTITER const s_end = list_end( s );
272
273 while ( !status && ( t_it != t_end || s_it != s_end ) )
274 {
275 char const * st = t_it != t_end ? object_str( list_item( t_it ) ) : "";
276 char const * ss = s_it != s_end ? object_str( list_item( s_it ) ) : "";
277
278 status = strcmp( st, ss );
279
280 t_it = t_it != t_end ? list_next( t_it ) : t_it;
281 s_it = s_it != s_end ? list_next( s_it ) : s_it;
282 }
283
284 return status;
285}
286
1e59de90 287int32_t list_is_sublist( LIST * sub, LIST * l )
7c673cae
FG
288{
289 LISTITER iter = list_begin( sub );
290 LISTITER const end = list_end( sub );
291 for ( ; iter != end; iter = list_next( iter ) )
292 if ( !list_in( l, list_item( iter ) ) )
293 return 0;
294 return 1;
295}
296
297/*
298 * list_print() - print a list of strings to stdout
299 */
300
301void list_print( LIST * l )
302{
303 LISTITER iter = list_begin( l ), end = list_end( l );
304 if ( iter != end )
305 {
306 out_printf( "%s", object_str( list_item( iter ) ) );
307 iter = list_next( iter );
308 for ( ; iter != end; iter = list_next( iter ) )
309 out_printf( " %s", object_str( list_item( iter ) ) );
310 }
311}
312
313
314/*
315 * list_length() - return the number of items in the list
316 */
317
1e59de90 318int32_t list_length( LIST * l )
7c673cae
FG
319{
320 return l ? l->impl.size : 0;
321}
322
323
1e59de90 324int32_t list_in( LIST * l, OBJECT * value )
7c673cae
FG
325{
326 LISTITER iter = list_begin( l );
327 LISTITER end = list_end( l );
328 for ( ; iter != end; iter = list_next( iter ) )
329 if ( object_equal( list_item( iter ), value ) )
330 return 1;
331 return 0;
332}
333
334
335LIST * list_unique( LIST * sorted_list )
336{
337 LIST * result = L0;
338 OBJECT * last_added = 0;
339
340 LISTITER iter = list_begin( sorted_list ), end = list_end( sorted_list );
341 for ( ; iter != end; iter = list_next( iter ) )
342 {
343 if ( !last_added || !object_equal( list_item( iter ), last_added ) )
344 {
345 result = list_push_back( result, object_copy( list_item( iter ) ) );
346 last_added = list_item( iter );
347 }
348 }
349 return result;
350}
351
352void list_done()
353{
7c673cae
FG
354}
355
356
357/*
358 * lol_init() - initialize a LOL (list of lists).
359 */
360
361void lol_init( LOL * lol )
362{
363 lol->count = 0;
364}
365
366
367/*
368 * lol_add() - append a LIST onto an LOL.
369 */
370
371void lol_add( LOL * lol, LIST * l )
372{
373 if ( lol->count < LOL_MAX )
1e59de90 374 {
7c673cae 375 lol->list[ lol->count++ ] = l;
1e59de90
TL
376 return;
377 }
378
379 err_printf( "lol_add failed due to reached limit of %d elements\n", LOL_MAX );
380 b2::clean_exit( EXITBAD );
7c673cae
FG
381}
382
383
384/*
385 * lol_free() - free the LOL and its LISTs.
386 */
387
388void lol_free( LOL * lol )
389{
1e59de90 390 int32_t i;
7c673cae
FG
391 for ( i = 0; i < lol->count; ++i )
392 list_free( lol->list[ i ] );
393 lol->count = 0;
394}
395
396
397/*
398 * lol_get() - return one of the LISTs in the LOL.
399 */
400
1e59de90 401LIST * lol_get( LOL * lol, int32_t i )
7c673cae
FG
402{
403 return i < lol->count ? lol->list[ i ] : L0;
404}
405
406
407/*
408 * lol_print() - debug print LISTS separated by ":".
409 */
410
411void lol_print( LOL * lol )
412{
1e59de90 413 int32_t i;
7c673cae
FG
414 for ( i = 0; i < lol->count; ++i )
415 {
416 if ( i )
417 out_printf( " : " );
418 list_print( lol->list[ i ] );
419 }
420}
421
422#ifdef HAVE_PYTHON
423
424PyObject * list_to_python( LIST * l )
425{
426 PyObject * result = PyList_New( 0 );
427 LISTITER iter = list_begin( l );
428 LISTITER const end = list_end( l );
429 for ( ; iter != end; iter = list_next( iter ) )
430 {
431 PyObject * s = PyString_FromString( object_str( list_item( iter ) ) );
432 PyList_Append( result, s );
433 Py_DECREF( s );
434 }
435
436 return result;
437}
438
439LIST * list_from_python( PyObject * l )
440{
441 LIST * result = L0;
442
443 Py_ssize_t n = PySequence_Size( l );
444 Py_ssize_t i;
445 for ( i = 0; i < n; ++i )
446 {
447 PyObject * v = PySequence_GetItem( l, i );
448 result = list_push_back( result, object_new( PyString_AsString( v ) ) );
449 Py_DECREF( v );
450 }
451
452 return result;
453}
454
455#endif