18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci#include <linux/slab.h> 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci/* 68c2ecf20Sopenharmony_ci * Merge two NULL-terminated pointer arrays into a newly allocated 78c2ecf20Sopenharmony_ci * array, which is also NULL-terminated. Nomenclature is inspired by 88c2ecf20Sopenharmony_ci * memset_p() and memcat() found elsewhere in the kernel source tree. 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_civoid **__memcat_p(void **a, void **b) 118c2ecf20Sopenharmony_ci{ 128c2ecf20Sopenharmony_ci void **p = a, **new; 138c2ecf20Sopenharmony_ci int nr; 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci /* count the elements in both arrays */ 168c2ecf20Sopenharmony_ci for (nr = 0, p = a; *p; nr++, p++) 178c2ecf20Sopenharmony_ci ; 188c2ecf20Sopenharmony_ci for (p = b; *p; nr++, p++) 198c2ecf20Sopenharmony_ci ; 208c2ecf20Sopenharmony_ci /* one for the NULL-terminator */ 218c2ecf20Sopenharmony_ci nr++; 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci new = kmalloc_array(nr, sizeof(void *), GFP_KERNEL); 248c2ecf20Sopenharmony_ci if (!new) 258c2ecf20Sopenharmony_ci return NULL; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci /* nr -> last index; p points to NULL in b[] */ 288c2ecf20Sopenharmony_ci for (nr--; nr >= 0; nr--, p = p == b ? &a[nr] : p - 1) 298c2ecf20Sopenharmony_ci new[nr] = *p; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci return new; 328c2ecf20Sopenharmony_ci} 338c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(__memcat_p); 348c2ecf20Sopenharmony_ci 35