1 /*
2  * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
3  * All rights reserved.  The file named COPYRIGHT specifies the terms
4  * and conditions for redistribution.
5  */
6 
7 
8 #include "config.h"
9 #include <stdlib.h>
10 #include "pset.h"
11 
12 
13 #define ALLOC_START				20
14 #define ALLOC_STEP				10
15 
16 
17 static __pset_pointer pset_insert( pset_h pset, const __pset_pointer p );
18 
19 
20 /*
21  * Create a pointer set and return a handle to it.
22  * Some space is initially allocated for the set.
23  */
pset_create(unsigned alloc_start,unsigned alloc_step)24 pset_h pset_create( unsigned alloc_start, unsigned alloc_step )
25 {
26 	pset_h pset ;
27 	unsigned start ;
28 
29 	pset = (pset_h) malloc( sizeof( struct __pset ) ) ;
30 	if ( pset == NULL )
31 		return( NULL ) ;
32 
33 	start = ( alloc_start == 0 ) ? ALLOC_START : alloc_start ;
34 	pset->ptrs = (__pset_pointer *) malloc( start * sizeof( __pset_pointer ) ) ;
35 	if ( pset->ptrs == NULL )
36 	{
37 		free( (char *) pset ) ;
38 		return( NULL ) ;
39 	}
40 
41 	pset->max = start ;
42 	pset->count = 0 ;
43 	pset->alloc_step = ( alloc_step == 0 ) ? ALLOC_STEP : alloc_step ;
44 	return( pset ) ;
45 }
46 
47 
48 /*
49  * Destroy a pset
50  */
pset_destroy(pset_h pset)51 void pset_destroy( pset_h pset )
52 {
53 	if ( pset == NULL )
54 		return;
55 	free( (char *) pset->ptrs ) ;
56 	free( (char *) pset ) ;
57 }
58 
pset_add(pset_h pset,const __pset_pointer ptr)59 __pset_pointer pset_add( pset_h pset, const __pset_pointer ptr )
60 {
61 	return (pset->count < pset->max )
62 		? (pset->ptrs[ pset->count++ ] = ptr)
63 			: pset_insert( pset, ptr) ;
64 }
65 
66 /*
67  * Append a pointer to a pset
68  */
pset_insert(pset_h pset,const __pset_pointer p)69 static __pset_pointer pset_insert( pset_h pset, const __pset_pointer p )
70 {
71 	if ( pset->count >= pset->max )
72 	{
73 		unsigned new_max = pset->max + pset->alloc_step ;
74 		__pset_pointer *new_ptrs ;
75 
76 		new_ptrs = (__pset_pointer *) realloc(
77 			(char *)pset->ptrs, new_max * sizeof( __pset_pointer ) ) ;
78 		if ( new_ptrs == NULL )
79 			return( NULL ) ;
80 		pset->max = new_max ;
81 		pset->ptrs = new_ptrs ;
82 	}
83 	return( pset->ptrs[ pset->count++ ] = p ) ;
84 }
85 
86 
87 /*
88  * Remove a pointer from a pset by moving every thing above it down 1 spot.
89  */
pset_delete(register pset_h pset,register const __pset_pointer ptr)90 void pset_delete( register pset_h pset, register const __pset_pointer ptr )
91 {
92 	register unsigned u = 0;
93 	register int found_it = 0;
94 
95 	if ( pset->count == 0 )
96 		return ;
97 
98 	while ( u < pset->count )
99 	{
100 		if ( pset->ptrs[ u ] == ptr )
101 			found_it = 1;
102 		if ( found_it )
103 		{	/* If not the last one, copy it */
104 			if ( (u+1) < pset->count )
105 				pset->ptrs[ u ] = pset->ptrs[ u+1 ];
106 		}
107 		u++;
108 	}
109 	pset->count--;
110 }
111 
112 
113 /*
114  * Create a pset iterator
115  */
psi_create(pset_h pset)116 psi_h psi_create( pset_h pset )
117 {
118 	psi_h iter = (psi_h) malloc( sizeof( struct __pset_iterator ) ) ;
119 
120 	if ( iter == NULL )
121 		return( NULL ) ;
122 	iter->pset = pset ;
123 	return( iter ) ;
124 }
125 
126 /*
127  * Remove an element from a pset
128  */
psi_remove(psi_h iter)129 void psi_remove( psi_h iter )
130 {
131 	if ( iter->current < pset_count( iter->pset ) )
132 	{
133 		pset_remove_index( iter->pset, iter->current ) ;
134 		iter->step = 0;
135 	}
136 }
137 
138