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  */
33 int
34 LDAP_CALL
ldap_charray_add(char *** a,char * s)35 ldap_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  */
69 int
70 LDAP_CALL
ldap_charray_merge(char *** a,char ** s)71 ldap_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 
101 void
102 LDAP_CALL
ldap_charray_free(char ** array)103 ldap_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 
119 int
120 LDAP_CALL
ldap_charray_inlist(char ** a,char * s)121 ldap_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  */
143 char **
144 LDAP_CALL
ldap_charray_dup(char ** a)145 ldap_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  */
179 char **
180 LDAP_CALL
ldap_str2charray(char * str,char * brkstr)181 ldap_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 
219 int
220 LDAP_CALL
ldap_charray_position(char ** a,char * s)221 ldap_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