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