Commit 4088e091 authored by David Zeuthen's avatar David Zeuthen

add doubly-linked lists

parent a28a6369
......@@ -85,6 +85,7 @@
<xi:include href="xml/polkit-types.xml"/>
<xi:include href="xml/polkit-sysdeps.xml"/>
<xi:include href="xml/polkit-memory.xml"/>
<xi:include href="xml/polkit-list.xml"/>
<xi:include href="xml/polkit-hash.xml"/>
<xi:include href="xml/polkit-error.xml"/>
<xi:include href="xml/polkit-result.xml"/>
......
......@@ -23,6 +23,7 @@ libpolkitinclude_HEADERS = \
polkit-sysdeps.h \
polkit-memory.h \
polkit-hash.h \
polkit-list.h \
polkit-types.h \
polkit-error.h \
polkit-result.h \
......@@ -46,6 +47,7 @@ libpolkit_la_SOURCES = \
polkit-types.h \
polkit-memory.h polkit-memory.c \
polkit-hash.h polkit-hash.c \
polkit-list.h polkit-list.c \
polkit-sysdeps.h polkit-sysdeps.c \
polkit-error.h polkit-error.c \
polkit-result.h polkit-result.c \
......
......@@ -38,7 +38,7 @@
/**
* SECTION:polkit-hash
* @title: Hash Tables
* @short_description: Hash Tables.
* @short_description: Hash Tables
*
* This class provides support for hash tables.
*
......
......@@ -91,6 +91,8 @@ typedef void (*PolKitFreeFunc) (void *p);
* object. The function polkit_hash_str_copy() or any of the object
* ref functions can be passed here.
*
* Returns: A copy or ref of the object in question
*
* Since: 0.7
*/
typedef void *(*PolKitCopyFunc) (const void *p);
......@@ -140,6 +142,6 @@ void *polkit_hash_str_copy (const void *p);
POLKIT_END_DECLS
#endif /* POLKIT_TEST_H */
#endif /* POLKIT_HASH_H */
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
/***************************************************************************
*
* polkit-list.c : Doubly-linked lists
*
* Copyright (C) 2007 David Zeuthen, <david@fubar.dk>
*
* Licensed under the Academic Free License version 2.1
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
**************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <polkit/polkit-list.h>
#include <polkit/polkit-memory.h>
#include <polkit/polkit-test.h>
/**
* SECTION:polkit-list
* @title: Doubly-linked lists
* @short_description: Doubly-linked lists
*
* This class provides support for doubly-linked lists.
*
* Since: 0.7
**/
/**
* polkit_list_append:
* @list: existing list or #NULL to create a new list
* @data: data to append to the list
*
* Append an entry to a list.
*
* Returns: the head of the new list or #NULL on OOM
*
* Since: 0.7
*/
PolKitList *
polkit_list_append (PolKitList *list, void *data)
{
PolKitList *l;
PolKitList *j;
for (j = list; j != NULL && j->next != NULL; j = j->next)
;
l = p_new0 (PolKitList, 1);
if (l == NULL)
goto oom;
l->data = data;
l->prev = j;
if (j != NULL) {
j->next = l;
} else {
list = l;
}
return list;
oom:
return NULL;
}
/**
* polkit_list_prepend:
* @list: existing list or #NULL to create a new list
* @data: data to prepend to the list
*
* Prepend an entry to a list.
*
* Returns: the head of the new list or #NULL on OOM
*
* Since: 0.7
*/
PolKitList *
polkit_list_prepend (PolKitList *list, void *data)
{
PolKitList *l;
l = p_new0 (PolKitList, 1);
if (l == NULL)
goto oom;
l->next = list;
l->data = data;
if (list != NULL) {
list->prev = l;
}
oom:
return l;
}
/**
* polkit_list_delete_link:
* @list: existing list, cannot be #NULL
* @link: link to delete, cannot be #NULL
*
* Delete a link from a list.
*
* Returns: the new head of the list or #NULL if the list is empty after deletion.
*
* Since: 0.7
*/
PolKitList *
polkit_list_delete_link (PolKitList *list, PolKitList *link)
{
PolKitList *ret;
g_return_val_if_fail (list != NULL, NULL);
g_return_val_if_fail (link != NULL, NULL);
if (list == link)
ret = link->next;
else
ret = list;
if (link->prev != NULL) {
link->prev->next = link->next;
}
if (link->next != NULL) {
link->next->prev = link->prev;
}
p_free (link);
return ret;
}
/**
* polkit_list_free:
* @list: the list
*
* Frees all links in a list
*
* Since: 0.7
*/
void
polkit_list_free (PolKitList *list)
{
PolKitList *l;
PolKitList *j;
for (l = list; l != NULL; l = j) {
j = l->next;
p_free (l);
}
}
/**
* polkit_list_length:
* @list: the list
*
* Compute the length of a list.
*
* Returns: Number of entries in list
*
* Since: 0.7
*/
size_t
polkit_list_length (PolKitList *list)
{
ssize_t n;
PolKitList *l;
n = 0;
for (l = list; l != NULL; l = l->next)
n++;
return n;
}
/**
* polkit_list_foreach:
* @list: the list
* @func: callback function
* @user_data: user data to pass to callback
*
* Iterate over all entries in a list.
*
* Returns: #TRUE only if the callback short-circuited the iteration
*
* Since: 0.7
*/
polkit_bool_t
polkit_list_foreach (PolKitList *list, PolKitListForeachFunc func, void *user_data)
{
PolKitList *l;
g_return_val_if_fail (list != NULL, FALSE);
g_return_val_if_fail (func != NULL, FALSE);
for (l = list; l != NULL; l = l->next) {
if (func (list, l->data, user_data))
return TRUE;
}
return FALSE;
}
#ifdef POLKIT_BUILD_TESTS
typedef struct {
int num;
int result;
} _Closure;
static polkit_bool_t
_sum (PolKitList *list, void *data, void *user_data)
{
_Closure *c = (_Closure*) user_data;
c->result += ((int) data) * (c->num + 1);
c->num += 1;
return FALSE;
}
static polkit_bool_t
_sum2 (PolKitList *list, void *data, void *user_data)
{
_Closure *c = (_Closure*) user_data;
if (c->num == 2)
return TRUE;
c->result += ((int) data) * (c->num + 1);
c->num += 1;
return FALSE;
}
static polkit_bool_t
_run_test (void)
{
_Closure c;
int items[] = {1, 2, 3, 4, 5};
unsigned int num_items = sizeof (items) / sizeof (int);
unsigned int n;
PolKitList *l;
PolKitList *j;
l = NULL;
for (n = 0; n < num_items; n++) {
j = l;
l = polkit_list_prepend (l, (void *) items[n]);
if (l == NULL)
goto oom;
}
g_assert (polkit_list_length (l) == num_items);
c.num = 0;
c.result = 0;
polkit_list_foreach (l, _sum, &c);
g_assert (c.result == 1*5 + 2*4 + 3*3 + 4*2 + 5*1);
c.num = 0;
c.result = 0;
polkit_list_foreach (l, _sum2, &c);
g_assert (c.result == 1*5 + 2*4);
l = polkit_list_delete_link (l, l);
g_assert (polkit_list_length (l) == num_items - 1);
c.num = 0;
c.result = 0;
polkit_list_foreach (l, _sum, &c);
g_assert (c.result == 1*4 + 2*3 + 3*2 + 4*1);
l = polkit_list_delete_link (l, l->next);
g_assert (polkit_list_length (l) == num_items - 2);
c.num = 0;
c.result = 0;
polkit_list_foreach (l, _sum, &c);
g_assert (c.result == 1*4 + 2*2 + 3*1);
polkit_list_free (l);
l = NULL;
for (n = 0; n < num_items; n++) {
j = l;
l = polkit_list_append (l, (void *) items[n]);
if (l == NULL)
goto oom;
}
c.num = 0;
c.result = 0;
polkit_list_foreach (l, _sum, &c);
g_assert (c.result == 1*1 + 2*2 + 3*3 + 4*4 + 5*5);
polkit_list_free (l);
return TRUE;
oom:
polkit_list_free (j);
return TRUE;
}
PolKitTest _test_list = {
"polkit_list",
NULL,
NULL,
_run_test
};
#endif /* POLKIT_BUILD_TESTS */
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
/***************************************************************************
*
* polkit-list.h : Doubly-linked list
*
* Copyright (C) 2007 David Zeuthen, <david@fubar.dk>
*
* Licensed under the Academic Free License version 2.1
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
**************************************************************************/
#if !defined (POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents."
#endif
#ifndef POLKIT_LIST_H
#define POLKIT_LIST_H
#include <polkit/polkit-types.h>
POLKIT_BEGIN_DECLS
struct _PolKitList;
typedef struct _PolKitList PolKitList;
/**
* PolKitList:
* @data: the value passed in polkit_list_append() and polkit_list_prepend()
* @next: the next element in the list or #NULL if this is the last element
* @prev: the previous element in the list or #NULL if this is the last element
*
* Public members of the #PolKitList data structure
*
* Since: 0.7
*/
struct _PolKitList {
void *data;
PolKitList *next;
PolKitList *prev;
};
/**
* PolKitListForeachFunc:
* @list: the list
* @data: data of link entry
* @user_data: user data passed to polkit_list_foreach()
*
* Type signature for callback function used in polkit_list_foreach().
*
* Returns: Return #TRUE to short-circuit, e.g. stop the iteration.
*
* Since: 0.7
*/
typedef polkit_bool_t (*PolKitListForeachFunc) (PolKitList *list,
void *data,
void *user_data);
PolKitList *polkit_list_append (PolKitList *list, void *data);
PolKitList *polkit_list_prepend (PolKitList *list, void *data);
void polkit_list_free (PolKitList *list);
PolKitList *polkit_list_delete_link (PolKitList *list, PolKitList *link);
size_t polkit_list_length (PolKitList *list);
polkit_bool_t polkit_list_foreach (PolKitList *list, PolKitListForeachFunc func, void *user_data);
POLKIT_END_DECLS
#endif /* POLKIT_LIST_H */
......@@ -138,7 +138,7 @@ p_malloc0 (size_t bytes)
/**
* p_realloc:
* @p: memory previously allocated
* @memory: memory previously allocated
* @bytes: new size
*
* Reallocate memory; like realloc(3).
......
......@@ -47,6 +47,7 @@
#include "polkit-debug.h"
#include "polkit-private.h"
#include "polkit-test.h"
#include "polkit-list.h"
/**
* SECTION:polkit-policy-file
......@@ -65,7 +66,7 @@
struct _PolKitPolicyFile
{
int refcount;
GSList *entries;
PolKitList *entries;
};
enum {
......@@ -385,6 +386,7 @@ static void
_end (void *data, const char *el)
{
ParserData *pd = data;
PolKitList *l;
p_free (pd->elem_lang);
pd->elem_lang = NULL;
......@@ -423,7 +425,12 @@ _end (void *data, const char *el)
}
}
pd->pf->entries = g_slist_prepend (pd->pf->entries, pfe);
l = polkit_list_prepend (pd->pf->entries, pfe);
if (l == NULL) {
polkit_policy_file_entry_unref (pfe);
goto oom;
}
pd->pf->entries = l;
break;
}
default:
......@@ -607,16 +614,16 @@ polkit_policy_file_ref (PolKitPolicyFile *policy_file)
void
polkit_policy_file_unref (PolKitPolicyFile *policy_file)
{
GSList *i;
PolKitList *i;
g_return_if_fail (policy_file != NULL);
policy_file->refcount--;
if (policy_file->refcount > 0)
return;
for (i = policy_file->entries; i != NULL; i = g_slist_next (i)) {
for (i = policy_file->entries; i != NULL; i = i->next) {
polkit_policy_file_entry_unref (i->data);
}
if (policy_file->entries != NULL)
g_slist_free (policy_file->entries);
polkit_list_free (policy_file->entries);
p_free (policy_file);
}
......@@ -633,12 +640,12 @@ polkit_policy_file_entry_foreach (PolKitPolicyFile *policy_file,
PolKitPolicyFileEntryForeachFunc cb,
void *user_data)
{
GSList *i;
PolKitList *i;
g_return_if_fail (policy_file != NULL);
g_return_if_fail (cb != NULL);
for (i = policy_file->entries; i != NULL; i = g_slist_next (i)) {
for (i = policy_file->entries; i != NULL; i = i->next) {
PolKitPolicyFileEntry *pfe = i->data;
cb (policy_file, pfe, user_data);
}
......
......@@ -32,6 +32,7 @@
#define MAX_TESTS 64
static PolKitTest *tests[] = {
&_test_list,
&_test_hash,
&_test_action,
&_test_error,
......
......@@ -60,6 +60,7 @@ extern PolKitTest _test_policy_default;
extern PolKitTest _test_policy_file_entry;
extern PolKitTest _test_hash;
extern PolKitTest _test_policy_file;
extern PolKitTest _test_list;
POLKIT_END_DECLS
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment