1#pragma ident	"%Z%%M%	%I%	%E% SMI"
2
3/*
4 * The contents of this file are subject to the Netscape Public
5 * License Version 1.1 (the "License"); you may not use this file
6 * except in compliance with the License. You may obtain a copy of
7 * the License at http://www.mozilla.org/NPL/
8 *
9 * Software distributed under the License is distributed on an "AS
10 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11 * implied. See the License for the specific language governing
12 * rights and limitations under the License.
13 *
14 * The Original Code is Mozilla Communicator client code, released
15 * March 31, 1998.
16 *
17 * The Initial Developer of the Original Code is Netscape
18 * Communications Corporation. Portions created by Netscape are
19 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
20 * Rights Reserved.
21 *
22 * Contributor(s):
23 */
24/* charray.c - routines for dealing with char * arrays */
25
26
27#include "ldap-int.h"
28
29/*
30 * Add s at the end of the array of strings *a.
31 * Return 0 for success, -1 for failure.
32 */
33int
34LDAP_CALL
35ldap_charray_add(
36    char	***a,
37    char	*s
38)
39{
40	int	n;
41
42	if ( *a == NULL ) {
43		*a = (char **)NSLDAPI_MALLOC( 2 * sizeof(char *) );
44		if ( *a == NULL ) {
45			return -1;
46		}
47		n = 0;
48	} else {
49		for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
50			;	/* NULL */
51		}
52
53		*a = (char **)NSLDAPI_REALLOC( (char *) *a,
54		    (n + 2) * sizeof(char *) );
55		if ( *a == NULL ) {
56			return -1;
57		}
58	}
59
60	(*a)[n++] = s;
61	(*a)[n] = NULL;
62	return 0;
63}
64
65/*
66 * Add array of strings s at the end of the array of strings *a.
67 * Return 0 for success, -1 for failure.
68 */
69int
70LDAP_CALL
71ldap_charray_merge(
72    char	***a,
73    char	**s
74)
75{
76	int	i, n, nn;
77
78	if ( (s == NULL) || (s[0] == NULL) )
79	    return 0;
80
81	for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
82		;	/* NULL */
83	}
84	for ( nn = 0; s[nn] != NULL; nn++ ) {
85		;	/* NULL */
86	}
87
88	*a = (char **)NSLDAPI_REALLOC( (char *) *a,
89	    (n + nn + 1) * sizeof(char *) );
90	if ( *a == NULL ) {
91		return -1;
92	}
93
94	for ( i = 0; i < nn; i++ ) {
95		(*a)[n + i] = s[i];
96	}
97	(*a)[n + nn] = NULL;
98	return 0;
99}
100
101void
102LDAP_CALL
103ldap_charray_free( char **array )
104{
105	char	**a;
106
107	if ( array == NULL ) {
108		return;
109	}
110
111	for ( a = array; *a != NULL; a++ ) {
112		if ( *a != NULL ) {
113			NSLDAPI_FREE( *a );
114		}
115	}
116	NSLDAPI_FREE( (char *) array );
117}
118
119int
120LDAP_CALL
121ldap_charray_inlist(
122    char	**a,
123    char	*s
124)
125{
126	int	i;
127
128	if ( a == NULL )
129		return( 0 );
130
131	for ( i = 0; a[i] != NULL; i++ ) {
132		if ( strcasecmp( s, a[i] ) == 0 ) {
133			return( 1 );
134		}
135	}
136
137	return( 0 );
138}
139
140/*
141 * Duplicate the array of strings a, return NULL upon any memory failure.
142 */
143char **
144LDAP_CALL
145ldap_charray_dup( char **a )
146{
147	int	i;
148	char	**new;
149
150	for ( i = 0; a[i] != NULL; i++ )
151		;	/* NULL */
152
153	new = (char **)NSLDAPI_MALLOC( (i + 1) * sizeof(char *) );
154	if ( new == NULL ) {
155		return NULL;
156	}
157
158	for ( i = 0; a[i] != NULL; i++ ) {
159		new[i] = nsldapi_strdup( a[i] );
160		if ( new[i] == NULL ) {
161			int	j;
162
163			for ( j = 0; j < i; j++ )
164			    NSLDAPI_FREE( new[j] );
165			NSLDAPI_FREE( new );
166			return NULL;
167		}
168	}
169	new[i] = NULL;
170
171	return( new );
172}
173
174/*
175 * Tokenize the string str, return NULL upon any memory failure.
176 * XXX: on many platforms this function is not thread safe because it
177 *	uses strtok().
178 */
179char **
180LDAP_CALL
181ldap_str2charray( char *str, char *brkstr )
182     /* This implementation fails if brkstr contains multibyte characters.
183        But it works OK if str is UTF-8 and brkstr is 7-bit ASCII.
184      */
185{
186	char	**res;
187	char	*s;
188	int	i;
189
190	i = 1;
191	for ( s = str; *s; s++ ) {
192		if ( strchr( brkstr, *s ) != NULL ) {
193			i++;
194		}
195	}
196
197	res = (char **)NSLDAPI_MALLOC( (i + 1) * sizeof(char *) );
198	if ( res == NULL ) {
199		return NULL;
200	}
201	i = 0;
202	for ( s = strtok( str, brkstr ); s != NULL; s = strtok( NULL,
203	    brkstr ) ) {
204		res[i++] = nsldapi_strdup( s );
205		if ( res[i - 1] == NULL ) {
206			int	j;
207
208			for ( j = 0; j < (i - 1); j++ )
209			    NSLDAPI_FREE( res[j] );
210			NSLDAPI_FREE( res );
211			return NULL;
212		}
213	}
214	res[i] = NULL;
215
216	return( res );
217}
218
219int
220LDAP_CALL
221ldap_charray_position( char **a, char *s )
222{
223	int     i;
224
225	for ( i = 0; a[i] != NULL; i++ ) {
226		if ( strcasecmp( s, a[i] ) == 0 ) {
227			return( i );
228		}
229	}
230
231	return( -1 );
232}
233