]> git.sur5r.net Git - openldap/blob - servers/slapd/charray.c
Moved bdb_strcopy to slap_strcopy
[openldap] / servers / slapd / charray.c
1 /* charray.c - routines for dealing with char * arrays */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/string.h>
13 #include <ac/socket.h>
14
15 #include "slap.h"
16
17 void
18 charray_add(
19     char        ***a,
20     const char  *s
21 )
22 {
23         int     n;
24
25         if ( *a == NULL ) {
26                 *a = (char **) ch_malloc( 2 * sizeof(char *) );
27                 n = 0;
28         } else {
29                 for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
30                         ;       /* NULL */
31                 }
32
33                 *a = (char **) ch_realloc( (char *) *a,
34                     (n + 2) * sizeof(char *) );
35         }
36
37         (*a)[n++] = ch_strdup(s);
38         (*a)[n] = NULL;
39 }
40
41 void
42 charray_add_n(
43     char        ***a,
44     const char  *s,
45     int         l
46 )
47 {
48         int     n;
49
50         if ( *a == NULL ) {
51                 *a = (char **) ch_malloc( 2 * sizeof(char *) );
52                 n = 0;
53         } else {
54                 for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
55                         ;       /* NULL */
56                 }
57
58                 *a = (char **) ch_realloc( (char *) *a,
59                     (n + 2) * sizeof(char *) );
60         }
61
62         (*a)[n] = (char *) ch_malloc( ( l + 1 ) * sizeof( char ) );
63         strncpy( (*a)[n], s, l );
64         (*a)[n][l] = '\0';
65         (*a)[++n] = NULL;
66 }
67
68 void
69 charray_merge(
70     char        ***a,
71     char        **s
72 )
73 {
74         int     i, n, nn;
75
76         for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
77                 ;       /* NULL */
78         }
79         for ( nn = 0; s[nn] != NULL; nn++ ) {
80                 ;       /* NULL */
81         }
82
83         *a = (char **) ch_realloc( (char *) *a, (n + nn + 1) * sizeof(char *) );
84
85         for ( i = 0; i < nn; i++ ) {
86                 (*a)[n + i] = ch_strdup(s[i]);
87         }
88         (*a)[n + nn] = NULL;
89 }
90
91 void
92 charray_free( char **array )
93 {
94         char    **a;
95
96         if ( array == NULL ) {
97                 return;
98         }
99
100         for ( a = array; *a != NULL; a++ ) {
101                 if ( *a != NULL ) {
102                         free( *a );
103                 }
104         }
105         free( (char *) array );
106 }
107
108 int
109 charray_inlist(
110     char        **a,
111     const char  *s
112 )
113 {
114         int     i;
115
116         if( a == NULL ) return 0;
117
118         for ( i = 0; a[i] != NULL; i++ ) {
119                 if ( strcasecmp( s, a[i] ) == 0 ) {
120                         return( 1 );
121                 }
122         }
123
124         return( 0 );
125 }
126
127 int
128 bvec_inlist(
129     struct berval **a,
130     struct berval *s
131 )
132 {
133         int     i;
134
135         if( a == NULL ) return 0;
136
137         for ( i = 0; a[i] != NULL; i++ ) {
138                 if ( a[i]->bv_len != s->bv_len) continue;
139                 if ( strcasecmp( s->bv_val, a[i]->bv_val ) == 0 ) {
140                         return( 1 );
141                 }
142         }
143
144         return( 0 );
145 }
146
147 char **
148 charray_dup( char **a )
149 {
150         int     i;
151         char    **new;
152
153         for ( i = 0; a[i] != NULL; i++ )
154                 ;       /* NULL */
155
156         new = (char **) ch_malloc( (i + 1) * sizeof(char *) );
157
158         for ( i = 0; a[i] != NULL; i++ ) {
159                 new[i] = ch_strdup( a[i] );
160         }
161         new[i] = NULL;
162
163         return( new );
164 }
165
166
167 char **
168 str2charray( const char *str_in, const char *brkstr )
169 {
170         char    *str;
171         char    **res;
172         char    *s;
173         char    *lasts;
174         int     i;
175
176         /* protect the input string from strtok */
177         str = ch_strdup( str_in );
178
179         i = 1;
180         for ( s = str; *s; s++ ) {
181                 if ( strchr( brkstr, *s ) != NULL ) {
182                         i++;
183                 }
184         }
185
186         res = (char **) ch_malloc( (i + 1) * sizeof(char *) );
187         i = 0;
188
189         for ( s = ldap_pvt_strtok( str, brkstr, &lasts );
190                 s != NULL;
191                 s = ldap_pvt_strtok( NULL, brkstr, &lasts ) )
192         {
193                 res[i++] = ch_strdup( s );
194         }
195
196         res[i] = NULL;
197
198         free( str );
199         return( res );
200 }
201
202 /* Convert a delimited string into an array of bervals; Add on
203  * to an existing array if it was given.
204  */
205 struct berval **
206 str2bvec( struct berval **vec, const char *in, const char *brkstr )
207 {
208         char    *str;
209         struct berval **res;
210         char    *s;
211         char    *lasts;
212         int     i, old;
213
214         /* protect the input string from strtok */
215         str = ch_strdup( in );
216
217         for (old = 0; vec && vec[old]; old++);
218         
219         i = 1;
220         for ( s = str; *s; s++ ) {
221                 if ( strchr( brkstr, *s ) != NULL ) {
222                         i++;
223                 }
224         }
225
226         if (vec) {
227                 res = (struct berval **) ch_realloc( vec, (old + i + 1) * sizeof(struct berval *) );
228                 vec = res + old;
229         } else {
230                 res = (struct berval **) ch_malloc( (i + 1) * sizeof(struct berval *) );
231                 vec = res;
232         }
233         i = 0;
234
235         for ( s = ldap_pvt_strtok( str, brkstr, &lasts );
236                 s != NULL;
237                 s = ldap_pvt_strtok( NULL, brkstr, &lasts ) )
238         {
239                 vec[i++] = ber_bvstrdup( s );
240         }
241
242         vec[i] = NULL;
243
244         free( str );
245         return( res );
246 }
247
248
249 int
250 charray_strcmp( const char **a1, const char **a2 )
251 {
252         for ( ; a1[0] && a2[0]; a1++, a2++ ) {
253                 if ( strcmp( a1[0], a2[0] ) ) {
254                         return( !0 );
255                 }
256         }
257
258         if ( ! ( a1[0] && a2[0] ) ) {
259                 return( !0 );
260         }
261
262         return 0;
263 }
264
265
266 int
267 charray_strcasecmp( const char **a1, const char **a2 )
268 {
269         for ( ; a1[0] && a2[0]; a1++, a2++ ) {
270                 if ( strcasecmp( a1[0], a2[0] ) ) {
271                         return( !0 );
272                 }
273         }
274
275         if ( ! ( a1[0] && a2[0] ) ) {
276                 return( !0 );
277         }
278
279         return 0;
280 }
281
282 /* strcopy is like strcpy except it returns a pointer to the trailing NUL of
283  * the result string. This allows fast construction of catenated strings
284  * without the overhead of strlen/strcat.
285  */
286 char *
287 slap_strcopy(
288         char *a,
289         char *b
290 )
291 {
292         if (!a || !b)
293                 return a;
294         
295         while (*a++ = *b++) ;
296         return a-1;
297 }