xref: /netbsd-src/external/bsd/openldap/dist/libraries/libldap/charray.c (revision 404fbe5fb94ca1e054339640cabb2801ce52dd30)
1 /* charray.c - routines for dealing with char * arrays */
2 /* $OpenLDAP: pkg/ldap/libraries/libldap/charray.c,v 1.16.2.3 2008/02/11 23:26:41 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 1998-2008 The OpenLDAP Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
12  * A copy of this license is available in the file LICENSE in the
13  * top-level directory of the distribution or, alternatively, at
14  * <http://www.OpenLDAP.org/license.html>.
15  */
16 
17 #include "portable.h"
18 
19 #include <stdio.h>
20 
21 #include <ac/string.h>
22 #include <ac/socket.h>
23 
24 #include "ldap-int.h"
25 
26 int
27 ldap_charray_add(
28     char	***a,
29     const char *s
30 )
31 {
32 	int	n;
33 
34 	if ( *a == NULL ) {
35 		*a = (char **) LDAP_MALLOC( 2 * sizeof(char *) );
36 		n = 0;
37 
38 		if( *a == NULL ) {
39 			return -1;
40 		}
41 
42 	} else {
43 		char **new;
44 
45 		for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
46 			;	/* NULL */
47 		}
48 
49 		new = (char **) LDAP_REALLOC( (char *) *a,
50 		    (n + 2) * sizeof(char *) );
51 
52 		if( new == NULL ) {
53 			/* caller is required to call ldap_charray_free(*a) */
54 			return -1;
55 		}
56 
57 		*a = new;
58 	}
59 
60 	(*a)[n] = LDAP_STRDUP(s);
61 
62 	if( (*a)[n] == NULL ) {
63 		return 1;
64 	}
65 
66 	(*a)[++n] = NULL;
67 
68 	return 0;
69 }
70 
71 int
72 ldap_charray_merge(
73     char	***a,
74     char	**s
75 )
76 {
77 	int	i, n, nn;
78 	char **aa;
79 
80 	for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
81 		;	/* NULL */
82 	}
83 	for ( nn = 0; s[nn] != NULL; nn++ ) {
84 		;	/* NULL */
85 	}
86 
87 	aa = (char **) LDAP_REALLOC( (char *) *a, (n + nn + 1) * sizeof(char *) );
88 
89 	if( aa == NULL ) {
90 		return -1;
91 	}
92 
93 	*a = aa;
94 
95 	for ( i = 0; i < nn; i++ ) {
96 		(*a)[n + i] = LDAP_STRDUP(s[i]);
97 
98 		if( (*a)[n + i] == NULL ) {
99 			for( --i ; i >= 0 ; i-- ) {
100 				LDAP_FREE( (*a)[n + i] );
101 				(*a)[n + i] = NULL;
102 			}
103 			return -1;
104 		}
105 	}
106 
107 	(*a)[n + nn] = NULL;
108 	return 0;
109 }
110 
111 void
112 ldap_charray_free( char **a )
113 {
114 	char	**p;
115 
116 	if ( a == NULL ) {
117 		return;
118 	}
119 
120 	for ( p = a; *p != NULL; p++ ) {
121 		if ( *p != NULL ) {
122 			LDAP_FREE( *p );
123 		}
124 	}
125 
126 	LDAP_FREE( (char *) a );
127 }
128 
129 int
130 ldap_charray_inlist(
131     char	**a,
132     const char *s
133 )
134 {
135 	int	i;
136 
137 	if( a == NULL ) return 0;
138 
139 	for ( i=0; a[i] != NULL; i++ ) {
140 		if ( strcasecmp( s, a[i] ) == 0 ) {
141 			return 1;
142 		}
143 	}
144 
145 	return 0;
146 }
147 
148 char **
149 ldap_charray_dup( char **a )
150 {
151 	int	i;
152 	char	**new;
153 
154 	for ( i = 0; a[i] != NULL; i++ )
155 		;	/* NULL */
156 
157 	new = (char **) LDAP_MALLOC( (i + 1) * sizeof(char *) );
158 
159 	if( new == NULL ) {
160 		return NULL;
161 	}
162 
163 	for ( i = 0; a[i] != NULL; i++ ) {
164 		new[i] = LDAP_STRDUP( a[i] );
165 
166 		if( new[i] == NULL ) {
167 			for( --i ; i >= 0 ; i-- ) {
168 				LDAP_FREE( new[i] );
169 			}
170 			LDAP_FREE( new );
171 			return NULL;
172 		}
173 	}
174 	new[i] = NULL;
175 
176 	return( new );
177 }
178 
179 char **
180 ldap_str2charray( const char *str_in, const char *brkstr )
181 {
182 	char	**res;
183 	char	*str, *s;
184 	char	*lasts;
185 	int	i;
186 
187 	/* protect the input string from strtok */
188 	str = LDAP_STRDUP( str_in );
189 	if( str == NULL ) {
190 		return NULL;
191 	}
192 
193 	i = 1;
194 	for ( s = str; *s; s++ ) {
195 		if ( ldap_utf8_strchr( brkstr, s ) != NULL ) {
196 			i++;
197 		}
198 	}
199 
200 	res = (char **) LDAP_MALLOC( (i + 1) * sizeof(char *) );
201 
202 	if( res == NULL ) {
203 		LDAP_FREE( str );
204 		return NULL;
205 	}
206 
207 	i = 0;
208 
209 	for ( s = ldap_utf8_strtok( str, brkstr, &lasts );
210 		s != NULL;
211 		s = ldap_utf8_strtok( NULL, brkstr, &lasts ) )
212 	{
213 		res[i] = LDAP_STRDUP( s );
214 
215 		if(res[i] == NULL) {
216 			for( --i ; i >= 0 ; i-- ) {
217 				LDAP_FREE( res[i] );
218 			}
219 			LDAP_FREE( res );
220 			LDAP_FREE( str );
221 			return NULL;
222 		}
223 
224 		i++;
225 	}
226 
227 	res[i] = NULL;
228 
229 	LDAP_FREE( str );
230 	return( res );
231 }
232 
233 char * ldap_charray2str( char **a, const char *sep )
234 {
235 	char *s, **v, *p;
236 	int len;
237 	int slen;
238 
239 	if( sep == NULL ) sep = " ";
240 
241 	slen = strlen( sep );
242 	len = 0;
243 
244 	for ( v = a; *v != NULL; v++ ) {
245 		len += strlen( *v ) + slen;
246 	}
247 
248 	if ( len == 0 ) {
249 		return NULL;
250 	}
251 
252 	/* trim extra sep len */
253 	len -= slen;
254 
255 	s = LDAP_MALLOC ( len + 1 );
256 
257 	if ( s == NULL ) {
258 		return NULL;
259 	}
260 
261 	p = s;
262 	for ( v = a; *v != NULL; v++ ) {
263 		if ( v != a ) {
264 			strncpy( p, sep, slen );
265 			p += slen;
266 		}
267 
268 		len = strlen( *v );
269 		strncpy( p, *v, len );
270 		p += len;
271 	}
272 
273 	*p = '\0';
274 	return s;
275 }
276