/* librc-strlist.h String list functions for using char ** arrays Copyright 2007 Gentoo Foundation Based on a previous implementation by Martin Schlemmer Released under the GPLv2 */ #include "librc.h" static char *_rc_strlist_add (char ***list, const char *item, bool uniq) { char **newlist; char **lst = *list; int i = 0; if (! item) return (NULL); while (lst && lst[i]) { if (uniq && strcmp (lst[i], item) == 0) { errno = EEXIST; return (NULL); } i++; } newlist = xrealloc (lst, sizeof (char *) * (i + 2)); newlist[i] = strdup (item); newlist[i + 1] = NULL; *list = newlist; return (newlist[i]); } char *rc_strlist_add (char ***list, const char *item) { return (_rc_strlist_add (list, item, false)); } librc_hidden_def(rc_strlist_add) char *rc_strlist_addu (char ***list, const char *item) { return (_rc_strlist_add (list, item, true)); } librc_hidden_def(rc_strlist_addu) static char *_rc_strlist_addsort (char ***list, const char *item, int (*sortfunc) (const char *s1, const char *s2), bool uniq) { char **newlist; char **lst = *list; int i = 0; char *tmp1; char *tmp2; char *retval; if (! item) return (NULL); while (lst && lst[i]) { if (uniq && strcmp (lst[i], item) == 0) { errno = EEXIST; return (NULL); } i++; } newlist = xrealloc (lst, sizeof (char *) * (i + 2)); if (! i) newlist[i] = NULL; newlist[i + 1] = NULL; i = 0; while (newlist[i] && sortfunc (newlist[i], item) < 0) i++; tmp1 = newlist[i]; retval = newlist[i] = strdup (item); do { i++; tmp2 = newlist[i]; newlist[i] = tmp1; tmp1 = tmp2; } while (tmp1); *list = newlist; return (retval); } char *rc_strlist_addsort (char ***list, const char *item) { return (_rc_strlist_addsort (list, item, strcoll, false)); } librc_hidden_def(rc_strlist_addsort) char *rc_strlist_addsortc (char ***list, const char *item) { return (_rc_strlist_addsort (list, item, strcmp, false)); } librc_hidden_def(rc_strlist_addsortc) char *rc_strlist_addsortu (char ***list, const char *item) { return (_rc_strlist_addsort (list, item, strcmp, true)); } librc_hidden_def(rc_strlist_addsortu) bool rc_strlist_delete (char ***list, const char *item) { char **lst = *list; int i = 0; bool retval = false; if (!lst || ! item) return (false); while (lst[i]) if (! strcmp (lst[i], item)) { free (lst[i]); retval = true; do { lst[i] = lst[i + 1]; i++; } while (lst[i]); } if (! retval) errno = ENOENT; return (retval); } librc_hidden_def(rc_strlist_delete) char *rc_strlist_join (char ***list1, char **list2) { char **lst1 = *list1; char **newlist; int i = 0; int j = 0; if (! list2) return (NULL); while (lst1 && lst1[i]) i++; while (list2[j]) j++; newlist = xrealloc (lst1, sizeof (char *) * (i + j + 1)); j = 0; while (list2[j]) { newlist[i] = list2[j]; /* Take the item off the 2nd list as it's only a shallow copy */ list2[j] = NULL; i++; j++; } newlist[i] = NULL; *list1 = newlist; return (newlist[i == 0 ? 0 : i - 1]); } librc_hidden_def(rc_strlist_join) void rc_strlist_reverse (char **list) { char *item; int i = 0; int j = 0; if (! list) return; while (list[j]) j++; j--; while (i < j && list[i] && list[j]) { item = list[i]; list[i] = list[j]; list[j] = item; i++; j--; } } librc_hidden_def(rc_strlist_reverse) void rc_strlist_free (char **list) { int i = 0; if (! list) return; while (list[i]) free (list[i++]); free (list); } librc_hidden_def(rc_strlist_free)