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