diff --git a/man/rc_stringlist.3 b/man/rc_stringlist.3 new file mode 100644 index 00000000..ca5019b8 --- /dev/null +++ b/man/rc_stringlist.3 @@ -0,0 +1,88 @@ +.\" Copyright 2007-2008 Roy Marples +.\" All rights reserved +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd Mar 16, 2008 +.Dt RC_STRLIST 3 SMM +.Os OpenRC +.Sh NAME +.Nm rc_stringlist_add , rc_stringlist_addu , rc_stringlist_delete , +.Nm rc_stringlist_free , rc_stringlist_new , rc_stringlist_sort +.Nd RC string list functions +.Sh LIBRARY +Run Command library (librc, -lrc) +.Sh SYNOPSIS +.In rc.h +.Ft "RC_STRINGLIST *" Fn rc_stringlist_new void +.Ft "RC_STRING *" Fn rc_stringlist_add "RC_STRINGLIST *list" "const char *item" +.Ft "RC_STRING *" Fn rc_stringlist_addu "RC_STRINGLIST *list" "const char *item" +.Ft bool Fn rc_stringlist_delete RC_STRINGLIST "const char *item" +.Ft void Fn rc_stringlist_free "RC_STRINGLIST *list" +.Ft void Fn rc_stringlist_sort "RC_STRINGLIST *list" +.Sh DESCRIPTION +These functions provide an easy means of manipulating string lists. They are +basically wrappers around TAILQ macros found in +.Xr queue 3 . +.Pp +.Fn rc_stringlist_new +creates a new list head to store the list. +.Pp +.Fn rc_stringlist_add +adds a malloced copy of +.Fa item +to +.Fa list . +It returns a pointer to the new item on success, or NULL on failure and sets +.Va errno +accordingly. +.Fn rc_stringlist_addu +only works if +.Fa list +does not already contain +.Fa item . +.Pp +.Fn rc_stringlist_delete +removes and frees +.Fa item +from +.Fa list , +retuning true on success, otherwise false. +.Pp +.Fn rc_stringlist_sort +sorts the +.Fa list +according to C locale. +.Pp +.Fn rc_stringlist_free +frees each item on +.Fa list +and the +.Fa list +itself. +.Sh SEE ALSO +.Xr malloc 3 , +.Xr free 3 , +.Xr queue 3 , +.Xr strcmp 3 +.Sh AUTHORS +.An "Roy Marples" Aq roy@marples.name diff --git a/src/librc/librc-stringlist.c b/src/librc/librc-stringlist.c new file mode 100644 index 00000000..93297ce9 --- /dev/null +++ b/src/librc/librc-stringlist.c @@ -0,0 +1,128 @@ +/* + librc-strlist.h + String list functions to make using queue(3) a little easier. + */ + +/* + * Copyright 2007-2008 Roy Marples + * All rights reserved + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "librc.h" + +RC_STRINGLIST *rc_stringlist_new(void) +{ + RC_STRINGLIST *l = xmalloc(sizeof(*l)); + TAILQ_INIT(l); + return l; +} + +RC_STRING *rc_stringlist_add (RC_STRINGLIST *list, const char *value) +{ + RC_STRING *s = xmalloc(sizeof(*s)); + + s->value = xstrdup(value); + TAILQ_INSERT_TAIL(list, s, entries); + return s; +} +librc_hidden_def(rc_stringlist_add) + +RC_STRING *rc_stringlist_addu (RC_STRINGLIST *list, const char *value) +{ + RC_STRING *s; + + TAILQ_FOREACH(s, list, entries) + if (strcmp(s->value, value) == 0) { + errno = EEXIST; + return NULL; + } + + return rc_stringlist_add(list, value); +} +librc_hidden_def(rc_stringlist_addu) + +bool rc_stringlist_delete (RC_STRINGLIST *list, const char *value) +{ + RC_STRING *s; + + TAILQ_FOREACH(s, list, entries) + if (strcmp(s->value, value) == 0) { + TAILQ_REMOVE(list, s, entries); + free (s->value); + free (s); + return true; + } + + errno = EEXIST; + return false; +} +librc_hidden_def(rc_stringlist_delete) + +void rc_stringlist_sort(RC_STRINGLIST **list) +{ + RC_STRINGLIST *l = *list; + RC_STRINGLIST *new = rc_stringlist_new(); + RC_STRING *s; + RC_STRING *sn; + RC_STRING *n; + RC_STRING *last; + + TAILQ_FOREACH_SAFE(s, l, entries, sn) { + TAILQ_REMOVE(l, s, entries); + last = NULL; + TAILQ_FOREACH (n, new, entries) { + if (strcmp (s->value, n->value) < 0) + break; + last = n; + } + if (last) + TAILQ_INSERT_AFTER(new, last, s, entries); + else + TAILQ_INSERT_HEAD(new, s, entries); + } + + /* Now we've sorted the list, copy across the new head */ + free(l); + *list = new; +} +librc_hidden_def(rc_stringlist_sort) + +void rc_stringlist_free(RC_STRINGLIST *list) +{ + RC_STRING *s1; + RC_STRING *s2; + + if (!list) + return; + + s1 = TAILQ_FIRST(list); + while (s1) { + s2 = TAILQ_NEXT(s1, entries); + free(s1->value); + free(s1); + s1 = s2; + } + free(list); +} +librc_hidden_def(rc_stringlist_free)