charray.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. /* charray.c - routines for dealing with char * arrays */
  39. #include <stdio.h>
  40. #include <string.h>
  41. #include <sys/types.h>
  42. #ifndef _WIN32
  43. #include <sys/socket.h>
  44. #endif
  45. #include "slap.h"
  46. void
  47. charray_add(
  48. char ***a,
  49. char *s
  50. )
  51. {
  52. int n;
  53. if ( *a == NULL ) {
  54. *a = (char **) slapi_ch_malloc( 2 * sizeof(char *) );
  55. n = 0;
  56. } else {
  57. for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
  58. ; /* NULL */
  59. }
  60. *a = (char **) slapi_ch_realloc( (char *) *a,
  61. (n + 2) * sizeof(char *) );
  62. }
  63. /* At this point, *a may be different from the value it had when this
  64. * function is called. Furthermore, *a[n] may contain an arbitrary
  65. * value, such as a pointer to the middle of a unallocated area.
  66. */
  67. #ifdef TEST_BELLATON
  68. (*a)[n+1] = NULL;
  69. (*a)[n] = s;
  70. #endif
  71. /* Putting code back so that thread conflict can be made visible */
  72. (*a)[n++] = s;
  73. (*a)[n] = NULL;
  74. }
  75. void
  76. charray_merge(
  77. char ***a,
  78. char **s,
  79. int copy_strs
  80. )
  81. {
  82. int i, n, nn;
  83. if ( (s == NULL) || (s[0] == NULL) )
  84. return;
  85. for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
  86. ; /* NULL */
  87. }
  88. for ( nn = 0; s[nn] != NULL; nn++ ) {
  89. ; /* NULL */
  90. }
  91. *a = (char **) slapi_ch_realloc( (char *) *a, (n + nn + 1) * sizeof(char *) );
  92. for ( i = 0; i < nn; i++ ) {
  93. if ( copy_strs ) {
  94. (*a)[n + i] = slapi_ch_strdup( s[i] );
  95. } else {
  96. (*a)[n + i] = s[i];
  97. }
  98. }
  99. (*a)[n + nn] = NULL;
  100. }
  101. /* Routines which don't pound on malloc. Don't interchange the arrays with the
  102. * regular calls---they can end up freeing non-heap memory, which is wrong */
  103. void
  104. cool_charray_free( char **array )
  105. {
  106. slapi_ch_free((void**)&array);
  107. }
  108. /* Like strcpy, but returns a pointer to the next byte after the last one written to */
  109. static char *strcpy_len(char *dest, char *source)
  110. {
  111. if('\0' == (*source)) {
  112. return(dest);
  113. }
  114. do {
  115. *dest++ = *source++;
  116. } while (*source);
  117. return dest;
  118. }
  119. char **
  120. cool_charray_dup( char **a )
  121. {
  122. int i,size, num_strings;
  123. char **newa;
  124. char *p;
  125. if ( a == NULL ) {
  126. return( NULL );
  127. }
  128. for ( i = 0; a[i] != NULL; i++ )
  129. ; /* NULL */
  130. num_strings = i;
  131. size = (i + 1) * sizeof(char *);
  132. for ( i = 0; a[i] != NULL; i++ ) {
  133. size += strlen( a[i] ) + 1;
  134. }
  135. newa = (char **) slapi_ch_malloc( size );
  136. p = (char *) &(newa[num_strings + 1]);
  137. for ( i = 0; a[i] != NULL; i++ ) {
  138. newa[i] = p;
  139. p = strcpy_len(p, a[i] );
  140. *p++ = '\0';
  141. }
  142. newa[i] = NULL;
  143. return( newa );
  144. }
  145. void
  146. charray_free( char **array )
  147. {
  148. char **a;
  149. if ( array == NULL ) {
  150. return;
  151. }
  152. for ( a = array; *a != NULL; a++ )
  153. {
  154. char *tmp= *a;
  155. slapi_ch_free((void**)&tmp);
  156. }
  157. slapi_ch_free( (void**)&array );
  158. }
  159. /*
  160. * charray_free version for plugins: there is a need for plugins to free
  161. * the ch_arrays returned by functions like:
  162. * slapi_get_supported_extended_ops_copy
  163. * slapi_get_supported_saslmechanisms_copy
  164. * slapi_get_supported_controls_copy
  165. */
  166. void
  167. slapi_ch_array_free( char **array )
  168. {
  169. charray_free (array);
  170. }
  171. /* case insensitive search */
  172. int
  173. charray_inlist(
  174. char **a,
  175. char *s
  176. )
  177. {
  178. int i;
  179. if ( a == NULL ) {
  180. return( 0 );
  181. }
  182. for ( i = 0; a[i] != NULL; i++ ) {
  183. if ( strcasecmp( s, a[i] ) == 0 ) {
  184. return( 1 );
  185. }
  186. }
  187. return( 0 );
  188. }
  189. /* case insensitive search covering non-ascii */
  190. int
  191. charray_utf8_inlist(
  192. char **a,
  193. char *s
  194. )
  195. {
  196. int i;
  197. if ( a == NULL ) {
  198. return( 0 );
  199. }
  200. for ( i = 0; a[i] != NULL; i++ ) {
  201. if (!slapi_UTF8CASECMP(a[i], s)) {
  202. return( 1 );
  203. }
  204. }
  205. return( 0 );
  206. }
  207. char **
  208. charray_dup( char **a )
  209. {
  210. int i;
  211. char **newa;
  212. if ( a == NULL ) {
  213. return( NULL );
  214. }
  215. for ( i = 0; a[i] != NULL; i++ )
  216. ; /* NULL */
  217. newa = (char **) slapi_ch_malloc( (i + 1) * sizeof(char *) );
  218. for ( i = 0; a[i] != NULL; i++ ) {
  219. newa[i] = slapi_ch_strdup( a[i] );
  220. }
  221. newa[i] = NULL;
  222. return( newa );
  223. }
  224. char **
  225. str2charray( char *str, char *brkstr )
  226. {
  227. char **res;
  228. char *s;
  229. int i;
  230. char * iter = NULL;
  231. i = 1;
  232. for ( s = str; *s; s++ ) {
  233. if ( strchr( brkstr, *s ) != NULL ) {
  234. i++;
  235. }
  236. }
  237. res = (char **) slapi_ch_malloc( (i + 1) * sizeof(char *) );
  238. i = 0;
  239. for ( s = ldap_utf8strtok_r( str, brkstr , &iter); s != NULL;
  240. s = ldap_utf8strtok_r( NULL, brkstr , &iter) ) {
  241. res[i++] = slapi_ch_strdup( s );
  242. }
  243. res[i] = NULL;
  244. return( res );
  245. }
  246. void
  247. charray_print( char **a )
  248. {
  249. int i;
  250. printf( "charray_print:\n");
  251. for ( i = 0; a!= NULL && a[i] != NULL; i++ ) {
  252. printf( "\t%s\n", a[i]);
  253. }
  254. }
  255. /*
  256. * Remove the char string from the array of char strings.
  257. * Performs a case *insensitive* comparison!
  258. * Just shunts the strings down to cover the deleted string.
  259. * Doesn't free up the unused memory.
  260. * Returns 1 if the entry found and removed, 0 if not.
  261. */
  262. int
  263. charray_remove(
  264. char **a,
  265. const char *s
  266. )
  267. {
  268. int i;
  269. int found= 0;
  270. for ( i=0; a!= NULL && a[i] != NULL; i++ )
  271. {
  272. if ( !found && strcasecmp (a[i],s) == 0 )
  273. {
  274. found= 1;
  275. }
  276. if (found)
  277. {
  278. a[i]= a[i+1];
  279. }
  280. }
  281. return found;
  282. }
  283. /*
  284. * if c == NULL, a = a - b
  285. * if c != NULL, *c = a - b
  286. */
  287. #define SUBTRACT_DEL (char *)(-1)
  288. void
  289. charray_subtract(char **a, char **b, char ***c)
  290. {
  291. char **bp, **cp, **tmp;
  292. char **p;
  293. if (c)
  294. tmp = *c = cool_charray_dup(a);
  295. else
  296. tmp = a;
  297. for (cp = tmp; cp && *cp; cp++) {
  298. for (bp = b; bp && *bp; bp++) {
  299. if (!slapi_UTF8CASECMP(*cp, *bp)) {
  300. slapi_ch_free((void **)&*cp);
  301. *cp = SUBTRACT_DEL;
  302. break;
  303. }
  304. }
  305. }
  306. for (cp = tmp; cp && *cp; cp++) {
  307. if (*cp == SUBTRACT_DEL) {
  308. for (p = cp+1; *p && *p == (char *)SUBTRACT_DEL; p++)
  309. ;
  310. *cp = *p;
  311. if (*p == NULL)
  312. break;
  313. else
  314. *p = SUBTRACT_DEL;
  315. }
  316. }
  317. }
  318. int
  319. charray_get_index(char **array, char *s)
  320. {
  321. int i;
  322. for (i = 0; array && array[i]; i++)
  323. {
  324. if (!slapi_UTF8CASECMP(array[i], s))
  325. return i;
  326. }
  327. return -1;
  328. }