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 #include "ldap-int.h"
40
41 /*
42 * Add s at the end of the array of strings *a.
43 * Return 0 for success, -1 for failure.
44 */
ldap_charray_add(char *** a,char * s)45 int LDAP_CALL ldap_charray_add(char*** a, char* s) {
46 int n;
47
48 if (*a == NULL) {
49 *a = (char**)NSLDAPI_MALLOC(2 * sizeof(char*));
50 if (*a == NULL) {
51 return -1;
52 }
53 n = 0;
54 } else {
55 for (n = 0; *a != NULL && (*a)[n] != NULL; n++) {
56 ; /* NULL */
57 }
58
59 *a = (char**)NSLDAPI_REALLOC((char*)*a, (n + 2) * sizeof(char*));
60 if (*a == NULL) {
61 return -1;
62 }
63 }
64
65 (*a)[n++] = s;
66 (*a)[n] = NULL;
67 return 0;
68 }
69
70 /*
71 * Add array of strings s at the end of the array of strings *a.
72 * Return 0 for success, -1 for failure.
73 */
ldap_charray_merge(char *** a,char ** s)74 int LDAP_CALL ldap_charray_merge(char*** a, char** s) {
75 int i, n, nn;
76
77 if ((s == NULL) || (s[0] == NULL)) return 0;
78
79 for (n = 0; *a != NULL && (*a)[n] != NULL; n++) {
80 ; /* NULL */
81 }
82 for (nn = 0; s[nn] != NULL; nn++) {
83 ; /* NULL */
84 }
85
86 *a = (char**)NSLDAPI_REALLOC((char*)*a, (n + nn + 1) * sizeof(char*));
87 if (*a == NULL) {
88 return -1;
89 }
90
91 for (i = 0; i < nn; i++) {
92 (*a)[n + i] = s[i];
93 }
94 (*a)[n + nn] = NULL;
95 return 0;
96 }
97
ldap_charray_free(char ** array)98 void LDAP_CALL ldap_charray_free(char** array) {
99 char** a;
100
101 if (array == NULL) {
102 return;
103 }
104
105 for (a = array; *a != NULL; a++) {
106 if (*a != NULL) {
107 NSLDAPI_FREE(*a);
108 }
109 }
110 NSLDAPI_FREE((char*)array);
111 }
112
ldap_charray_inlist(char ** a,char * s)113 int LDAP_CALL ldap_charray_inlist(char** a, char* s) {
114 int i;
115
116 if (a == NULL) return (0);
117
118 for (i = 0; a[i] != NULL; i++) {
119 if (strcasecmp(s, a[i]) == 0) {
120 return (1);
121 }
122 }
123
124 return (0);
125 }
126
127 /*
128 * Duplicate the array of strings a, return NULL upon any memory failure.
129 */
ldap_charray_dup(char ** a)130 char** LDAP_CALL ldap_charray_dup(char** a) {
131 int i;
132 char** new;
133
134 for (i = 0; a[i] != NULL; i++)
135 ; /* NULL */
136
137 new = (char**)NSLDAPI_MALLOC((i + 1) * sizeof(char*));
138 if (new == NULL) {
139 return NULL;
140 }
141
142 for (i = 0; a[i] != NULL; i++) {
143 new[i] = nsldapi_strdup(a[i]);
144 if (new[i] == NULL) {
145 int j;
146
147 for (j = 0; j < i; j++) NSLDAPI_FREE(new[j]);
148 NSLDAPI_FREE(new);
149 return NULL;
150 }
151 }
152 new[i] = NULL;
153
154 return (new);
155 }
156
157 /*
158 * Tokenize the string str, return NULL upon any memory failure.
159 * XXX: on many platforms this function is not thread safe because it
160 * uses strtok().
161 */
ldap_str2charray(char * str,char * brkstr)162 char** LDAP_CALL ldap_str2charray(char* str, char* brkstr)
163 /* This implementation fails if brkstr contains multibyte characters.
164 But it works OK if str is UTF-8 and brkstr is 7-bit ASCII.
165 */
166 {
167 char** res;
168 char* s;
169 int i;
170 #ifdef HAVE_STRTOK_R /* defined in portable.h */
171 char* lasts;
172 #endif
173
174 i = 1;
175 for (s = str; *s; s++) {
176 if (strchr(brkstr, *s) != NULL) {
177 i++;
178 }
179 }
180
181 res = (char**)NSLDAPI_MALLOC((i + 1) * sizeof(char*));
182 if (res == NULL) {
183 return NULL;
184 }
185 i = 0;
186 for (s = STRTOK(str, brkstr, &lasts); s != NULL;
187 s = STRTOK(NULL, brkstr, &lasts)) {
188 res[i++] = nsldapi_strdup(s);
189 if (res[i - 1] == NULL) {
190 int j;
191
192 for (j = 0; j < (i - 1); j++) NSLDAPI_FREE(res[j]);
193 NSLDAPI_FREE(res);
194 return NULL;
195 }
196 }
197 res[i] = NULL;
198
199 return (res);
200 }
201
ldap_charray_position(char ** a,char * s)202 int LDAP_CALL ldap_charray_position(char** a, char* s) {
203 int i;
204
205 for (i = 0; a[i] != NULL; i++) {
206 if (strcasecmp(s, a[i]) == 0) {
207 return (i);
208 }
209 }
210
211 return (-1);
212 }
213