From: Karl MacMillan <kmacmillan@mentalrootkit.com>
To: SELinux Mail List <selinux@tycho.nsa.gov>
Subject: [RFC] Add list and iter data types to libsepol
Date: Tue, 16 Jan 2007 16:10:41 -0500 [thread overview]
Message-ID: <45AD3F51.9070005@mentalrootkit.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 574 bytes --]
As part of some work to improve the parser in checkpolicy and module
data structures in libsepol, I have implemented doubly-linked list and
iterator data types. The attached patch adds these to libsepol.
I would appreciate feedback on these before I submit larger patches that
make use of them. In particular:
* Is the iterator concept acceptable (I plan to add iterator support to
other data types including hashtabs)?
* We've discussed dropping the use of typedefs on structs (which I do in
this patch). Is this what we want to do, or should I add typedefs?
Karl
[-- Attachment #2: sepol-list-iter.patch --]
[-- Type: text/x-patch, Size: 20785 bytes --]
diff -r 20ff5c9a577b libsepol/include/sepol/errcodes.h
--- a/libsepol/include/sepol/errcodes.h Tue Jan 16 15:50:54 2007 -0500
+++ b/libsepol/include/sepol/errcodes.h Tue Jan 16 16:04:16 2007 -0500
@@ -22,4 +22,7 @@
#define SEPOL_EEXIST -EEXIST
#define SEPOL_ENOENT -ENOENT
+/* Custom error codes */
+#define SEPOL_ITERSTOP -500
+
#endif
diff -r 20ff5c9a577b libsepol/include/sepol/policydb/iter.h
--- a/libsepol/include/sepol/policydb/iter.h Tue Jan 16 15:50:54 2007 -0500
+++ b/libsepol/include/sepol/policydb/iter.h Tue Jan 16 16:04:16 2007 -0500
@@ -0,0 +1,118 @@
+/* Author : Karl MacMillan <kmacmillan@mentalrootkit.com> */
+
+#ifndef __sepol_iter_h__
+#define __sepol_iter_h__
+
+/* Iterators represent a position within a data-structure. They are a
+ * generalization of the concept of pointers. Using iterators allows
+ * algorithms to be cleanly separated from data structures by
+ * abstracting the concept of position and movement. Once an iterator
+ * is created and its position initialized in a data structure
+ * specific way, looping and other control flow can be implemented
+ * only using the generic iterator functions.
+ *
+ * For example, consider the code below which loops through a list
+ * (the error handling is ommitted for brevity):
+ *
+ * int ret;
+ * struct sepol_iter *iter;
+ *
+ * sepol_iter_create(&iter);
+ * ret = sepol_list_begin(iter);
+ *
+ * while (ret == SEPOL_OK) {
+ * // process the data
+ * data = sepol_iter_get_data(iter);
+ * ret = sepol_iter_next(iter);
+ * }
+ * if (ret != SEPOL_ITERSTOP)
+ * // handle errors
+ */
+struct sepol_iter;
+
+/* Create an iterator. The iterator is not valid
+ * until a data structure specific call has been
+ * made to initiliaze its position (e.g., sepol_list_begin).
+ *
+ * Returns:
+ * SEPOL_OK: success
+ * SEPOL_ENOMEM: out of memory
+ */
+int sepol_iter_create(struct sepol_iter **iter);
+
+/* Destroy an iterator.
+ */
+void sepol_iter_destroy(struct sepol_iter *iter);
+
+/* Return the data at this iterator location. The type
+ * of the returned data is data structure specific.
+ *
+ * Returns:
+ * Non-null: data at this iterator position
+ * NULL: error
+ */
+void *sepol_iter_get_data(struct sepol_iter *iter);
+
+/* Move the iterator to the next position. If SEPOL_ITERSTOP is
+ * returned, one past the end of the data structure has been reached.
+ * No other calls using this iterator are valid until a data structure
+ * specific call has been made to reset it to a valid position (e.g.,
+ * sepol_list_begin).
+ *
+ * Returns:
+ * SEPOL_OK: iterator successfully moved
+ * SEPOL_ITERSTOP: iteration should stop
+ * < 0: other errors specific to the underlying data structure
+ */
+int sepol_iter_next(struct sepol_iter *iter);
+
+/* Move the iterator to the prev position. If SEPOL_ITERSTOP is
+ * returned, one before the beginning of the data structure has been
+ * reached. No other calls using this iterator are valid until a data
+ * structure specific call has been made to reset it to a valid
+ * position (e.g., sepol_list_end).
+ *
+ * Not all iterators support prev - the data structure specific
+ * iterator documentation should indicate whether prev is supported.
+ *
+ * Returns:
+ * SEPOL_OK: iterator successfully moved
+ * SEPOL_ITERSTOP: iteration should stop
+ * SEPOL_ENOTSUP: previous iterator not supported for this
+ * data structure.
+ * < 0: other errors specific to the underlying data structure
+ */
+int sepol_iter_prev(struct sepol_iter *iter);
+
+/* Move the iterator forward by distance. This does _not_ set the
+ * absolute position of the iterator. Rather, it moves in by distance
+ * from the current position. For example, moving an iterator at
+ * position 2 by 3 would put the iterator at position 5.
+ *
+ * Returns: same as sepol_iter_next
+ */
+int sepol_iter_forward(struct sepol_iter *iter, unsigned int distance);
+
+/* Move the iterator backward by distance. This does _not_ set the
+ * absolute position of the iterator. Rather, it moves in by distance
+ * from the current position. For example, moving an iterator at
+ * position 2 by 1 would put the iterator at position 1.
+ *
+ * Iterator must support sepol_iter_prev.
+ *
+ * Returns: same as sepol_iter_prev
+ */
+int sepol_iter_backward(struct sepol_iter *iter, unsigned int distance);
+
+/* used by implementations of iterators */
+void sepol_iter_set_state(struct sepol_iter *iter, void *state);
+void *sepol_iter_get_state(struct sepol_iter *iter);
+void sepol_iter_set_next(struct sepol_iter *iter,
+ int (*next)(struct sepol_iter *));
+void sepol_iter_set_prev(struct sepol_iter *iter,
+ int (*prev)(struct sepol_iter *));
+void sepol_iter_set_get_data(struct sepol_iter *iter,
+ void *(*get)(struct sepol_iter *));
+void sepol_iter_set_free(struct sepol_iter *iter, void (*state_free)(void *data));
+
+#endif
diff -r 20ff5c9a577b libsepol/include/sepol/policydb/list.h
--- a/libsepol/include/sepol/policydb/list.h Tue Jan 16 15:50:54 2007 -0500
+++ b/libsepol/include/sepol/policydb/list.h Tue Jan 16 16:04:16 2007 -0500
@@ -0,0 +1,79 @@
+/* Author : Karl MacMillan <kmacmillan@mentalrootkit.com> */
+
+
+#ifndef __sepol_list_h__
+#define __sepol_list_h__
+
+#include <sepol/policydb/iter.h>
+
+/* Doubly-linked list data type. */
+
+struct sepol_list;
+
+/* Create an sepol_list. On success, SEPOL_OK is returned
+ * and the list pointer passed in is set to an allocated
+ * sepol_list struct that has been initialized.
+ *
+ * Returns:
+ * SEPOL_OK: sepol_list successfully created
+ * SEPOL_ENOMEM: out of memory
+ */
+int sepol_list_create(struct sepol_list **list);
+
+/* Destroy an sepol_list. This will _not_ free the memory
+ * for the list items, only for the internal list structures.
+ * The list item memory should be freed by the caller. Note
+ * that this function can return an error.
+ */
+void sepol_list_destroy(struct sepol_list *list);
+
+/* Append an item to the list. If successful, the item will
+ * become the last item in the list.
+ *
+ * Returns:
+ * SEPOL_OK: success
+ * SEPOL_ENOMEM: out of memory
+ */
+int sepol_list_append(struct sepol_list *list, void *item);
+
+/* Prepend an item to the list. If successful, the item will
+ * become the first item in the list.
+ *
+ * Returns:
+ * SEPOL_OK: success
+ * SEPOL_ENOMEM: out of memory
+ */
+int sepol_list_prepend(struct sepol_list *list, void *item);
+
+/* Insert an item at the iterator position. The existing item
+ * is shifted to the next position in the list. The iterator
+ * continues to point at the same item, though the position of
+ * that item will have moved forward by one.
+ *
+ * Returns:
+ * SEPOL_OK: success
+ * SEPOL_ENOMEM: out of memory
+ */
+int sepol_list_insert(struct sepol_list *list, struct sepol_iter *iter, void *item);
+
+/* Position the iterator at the beginning of the list. If the list
+ * is empty SEPOL_ITERSTOP will be returned and the iterator will not
+ * be valid.
+ *
+ * Returns:
+ * SEPOL_OK: success
+ * SEPOL_ITERSTOP: empty list
+ */
+int sepol_list_begin(struct sepol_list *list, struct sepol_iter *iter);
+
+/* Position the iterator at the end of the list. If the list
+ * is empty SEPOL_ITERSTOP will be returned and the iterator will not
+ * be valid.
+ *
+ * Returns:
+ * SEPOL_OK: success
+ * SEPOL_ITERSTOP: empty list
+ */
+int sepol_list_end(struct sepol_list *list, struct sepol_iter *iter);
+
+#endif
diff -r 20ff5c9a577b libsepol/src/iter.c
--- a/libsepol/src/iter.c Tue Jan 16 15:50:54 2007 -0500
+++ b/libsepol/src/iter.c Tue Jan 16 16:04:16 2007 -0500
@@ -0,0 +1,141 @@
+/*
+ * Author : Karl MacMillan <kmacmillan@mentalrootkit.com>
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <sepol/policydb/iter.h>
+
+#include <sepol/errcodes.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+struct sepol_iter
+{
+ void *state;
+ int (*next)(struct sepol_iter *);
+ int (*prev)(struct sepol_iter *);
+ void *(*get)(struct sepol_iter *);
+ void (*free)(void *);
+};
+
+int sepol_iter_create(struct sepol_iter **iter)
+{
+ *iter = (struct sepol_iter*)calloc(1, sizeof(struct sepol_iter));
+ if (*iter == NULL)
+ return SEPOL_ENOMEM;
+
+ return SEPOL_OK;
+}
+
+void sepol_iter_destroy(struct sepol_iter *iter)
+{
+ if (iter->free != NULL)
+ iter->free(iter);
+ free(iter);
+}
+
+void *sepol_iter_get_data(struct sepol_iter *iter)
+{
+ assert(iter);
+ assert(iter->get);
+ return iter->get(iter);
+}
+
+int sepol_iter_next(struct sepol_iter *iter)
+{
+ assert(iter);
+ assert(iter->next);
+ return iter->next(iter);
+}
+
+int sepol_iter_prev(struct sepol_iter *iter)
+{
+ assert(iter);
+
+ if (iter->prev == NULL)
+ return SEPOL_ENOTSUP;
+
+ return iter->prev(iter);
+}
+
+int sepol_iter_forward(struct sepol_iter *iter, unsigned int distance)
+{
+ unsigned int i = 0;
+ int ret = SEPOL_OK;
+
+ while (i < distance && ret == SEPOL_OK) {
+ ret = sepol_iter_next(iter);
+ i++;
+ }
+
+ return ret;
+}
+
+int sepol_iter_backward(struct sepol_iter *iter, unsigned int distance)
+{
+ unsigned int i = 0;
+ int ret = SEPOL_OK;
+
+ while (i < distance && ret == SEPOL_OK) {
+ ret = sepol_iter_prev(iter);
+ i++;
+ }
+
+ return ret;
+}
+
+void sepol_iter_set_state(struct sepol_iter *iter, void *state)
+{
+ assert(iter);
+ iter->state = state;
+}
+
+void *sepol_iter_get_state(struct sepol_iter *iter)
+{
+ assert(iter);
+ return iter->state;
+}
+
+void sepol_iter_set_next(struct sepol_iter *iter,
+ int (*next)(struct sepol_iter *))
+{
+ assert(iter);
+ iter->next = next;
+}
+
+void sepol_iter_set_prev(struct sepol_iter *iter,
+ int (*prev)(struct sepol_iter *))
+{
+ assert(iter);
+ iter->prev = prev;
+}
+
+void sepol_iter_set_get_data(struct sepol_iter *iter,
+ void *(*get)(struct sepol_iter *))
+{
+ assert(iter);
+ iter->get = get;
+}
+
+void sepol_iter_set_free(struct sepol_iter *iter, void (*state_free)(void *))
+{
+ assert(iter);
+ iter->free = free;
+}
diff -r 20ff5c9a577b libsepol/src/list.c
--- a/libsepol/src/list.c Tue Jan 16 15:50:54 2007 -0500
+++ b/libsepol/src/list.c Tue Jan 16 16:04:16 2007 -0500
@@ -0,0 +1,253 @@
+/*
+ * Author : Karl MacMillan <kmacmillan@mentalrootkit.com>
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <sepol/errcodes.h>
+
+#include <sepol/policydb/list.h>
+#include <sepol/policydb/iter.h>
+
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct sepol_list_item
+{
+ struct sepol_list_item *next;
+ struct sepol_list_item *prev;
+ void *item;
+};
+
+struct sepol_list
+{
+ struct sepol_list_item *head;
+ struct sepol_list_item *tail;
+};
+
+int sepol_list_create(struct sepol_list **list)
+{
+ assert(list);
+
+ *list = (struct sepol_list *)calloc(1, sizeof(struct sepol_list));
+ if (*list == NULL)
+ return SEPOL_ENOMEM;
+
+ return SEPOL_OK;
+}
+
+void sepol_list_destroy(struct sepol_list *list)
+{
+ struct sepol_list_item *cur, *next;
+
+ if (list == NULL)
+ return;
+
+ cur = list->head;
+ while (cur != NULL) {
+ next = cur->next;
+ free(cur);
+ cur = next;
+ }
+
+ free(list);
+}
+
+static int sepol_list_item_create(struct sepol_list_item **x)
+{
+ *x = calloc(1, sizeof(struct sepol_list_item));
+ if (*x == NULL)
+ return SEPOL_ENOMEM;
+ else
+ return SEPOL_OK;
+}
+
+int sepol_list_append(struct sepol_list *list, void *item)
+{
+ int ret;
+ struct sepol_list_item *x;
+
+ assert(list);
+
+ ret = sepol_list_item_create(&x);
+ if (ret < 0)
+ return ret;
+ x->item = item;
+
+ /* empty list */
+ if (list->tail == NULL) {
+ list->tail = x;
+ list->head = x;
+ x->prev = NULL;
+ x->next = NULL;
+ } else {
+ list->tail->next = x;
+ x->prev = list->tail;
+ x->next = NULL;
+ list->tail = x;
+ }
+
+ return SEPOL_OK;
+}
+
+int sepol_list_prepend(struct sepol_list *list, void *item)
+{
+ int ret;
+ struct sepol_list_item *x;
+
+ assert(list);
+
+ ret = sepol_list_item_create(&x);
+ if (ret < 0)
+ return ret;
+ x->item = item;
+
+ /* empty list */
+ if (list->tail == NULL) {
+ list->tail = x;
+ list->head = x;
+ x->prev = NULL;
+ x->next = NULL;
+ } else {
+ x->next = list->head;
+ list->head->prev = x;
+ x->prev = NULL;
+ list->head = x;
+ }
+
+ return SEPOL_OK;
+}
+
+int sepol_list_insert(struct sepol_list *list, struct sepol_iter *iter, void *item)
+{
+ int ret;
+ struct sepol_list_item *x, *cur;
+
+ assert(list);
+
+ cur = (struct sepol_list_item*)sepol_iter_get_state(iter);
+ assert(cur);
+
+ /* Short circuit for prepend and append. */
+ if (list->head == cur) {
+ return sepol_list_prepend(list, item);
+ } else if (list->tail == cur) {
+ return sepol_list_append(list, item);
+ }
+
+ ret = sepol_list_item_create(&x);
+ if (ret < 0)
+ return ret;
+ x->item = item;
+
+ x->prev = cur->prev;
+ x->prev->next = x;
+ x->next = cur;
+ cur->prev = x;
+
+ return SEPOL_OK;
+}
+
+static int sepol_list_next(struct sepol_iter *iter)
+{
+ struct sepol_list_item *cur;
+
+ assert(iter);
+
+ cur = (struct sepol_list_item*)sepol_iter_get_state(iter);
+ assert(cur);
+
+ if (cur->next == NULL) {
+ /* set the state to NULL to catch using this iterator
+ * after ITERSTOP is returned (which is a bug). */
+ sepol_iter_set_state(iter, NULL);
+ return SEPOL_ITERSTOP;
+ } else {
+ sepol_iter_set_state(iter, cur->next);
+ return SEPOL_OK;
+ }
+}
+
+static int sepol_list_prev(struct sepol_iter *iter)
+{
+ struct sepol_list_item *cur;
+
+ assert(iter);
+
+ cur = (struct sepol_list_item*)sepol_iter_get_state(iter);
+ assert(cur);
+
+ if (cur->prev == NULL) {
+ /* set the state to NULL to catch using this iterator
+ * after ITERSTOP is returned (which is a bug). */
+ sepol_iter_set_state(iter, NULL);
+ return SEPOL_ITERSTOP;
+ } else {
+ sepol_iter_set_state(iter, cur->prev);
+ return SEPOL_OK;
+ }
+}
+
+static void *sepol_list_iter_get_data(struct sepol_iter *iter)
+{
+ struct sepol_list_item *cur;
+
+ assert(iter);
+
+ cur = (struct sepol_list_item*)sepol_iter_get_state(iter);
+ assert(cur);
+
+ return cur->item;
+}
+
+#define ITERSETUP(iter) { sepol_iter_set_next(iter, sepol_list_next); \
+ sepol_iter_set_prev(iter, sepol_list_prev); \
+ sepol_iter_set_get_data(iter, sepol_list_iter_get_data); }
+
+
+int sepol_list_begin(struct sepol_list *list, struct sepol_iter *iter)
+{
+ assert(list);
+ assert(iter);
+
+ if (list->head == NULL)
+ return SEPOL_ITERSTOP;
+
+ sepol_iter_set_state(iter, list->head);
+
+ ITERSETUP(iter);
+
+ return SEPOL_OK;
+}
+
+int sepol_list_end(struct sepol_list *list, struct sepol_iter *iter)
+{
+ assert(list);
+ assert(iter);
+
+ if (list->tail == NULL)
+ return SEPOL_ITERSTOP;
+
+ sepol_iter_set_state(iter, list->tail);
+
+ ITERSETUP(iter);
+
+ return SEPOL_OK;
+}
+
diff -r 20ff5c9a577b libsepol/tests/libsepol-tests.c
--- a/libsepol/tests/libsepol-tests.c Tue Jan 16 15:50:54 2007 -0500
+++ b/libsepol/tests/libsepol-tests.c Tue Jan 16 16:04:16 2007 -0500
@@ -22,6 +22,7 @@
#include "test-linker.h"
#include "test-expander.h"
#include "test-deps.h"
+#include "test-list.h"
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
@@ -61,6 +62,7 @@ static int do_tests(int interactive, int
DECLARE_SUITE(linker);
DECLARE_SUITE(expander);
DECLARE_SUITE(deps);
+ DECLARE_SUITE(list);
if (verbose)
CU_basic_set_mode(CU_BRM_VERBOSE);
diff -r 20ff5c9a577b libsepol/tests/test-list.c
--- a/libsepol/tests/test-list.c Tue Jan 16 15:50:54 2007 -0500
+++ b/libsepol/tests/test-list.c Tue Jan 16 16:04:16 2007 -0500
@@ -0,0 +1,145 @@
+/*
+ * Author : Karl MacMillan <kmacmillan@mentalrootkit.com>
+ *
+ * Copyright (C) 2006 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "test-list.h"
+
+#include <sepol/policydb/list.h>
+#include <sepol/policydb/iter.h>
+#include <sepol/errcodes.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int list_test_init(void)
+{
+ return 0;
+}
+
+int list_test_cleanup(void)
+{
+ return 0;
+}
+
+static void test_list_create(void)
+{
+ struct sepol_list *list;
+ int ret;
+
+ ret = sepol_list_create(&list);
+ CU_ASSERT(ret == 0);
+
+ sepol_list_destroy(list);
+}
+
+static void test_list(void)
+{
+ struct sepol_list *list;
+ struct sepol_iter *iter;
+ int ret;
+ int i, *num, nums[6];
+
+ for (i = 0; i < 6; i++)
+ nums[i] = i;
+
+ ret = sepol_iter_create(&iter);
+ CU_ASSERT(ret == 0);
+
+ ret = sepol_list_create(&list);
+ CU_ASSERT(ret == 0);
+
+ ret = sepol_list_append(list, &nums[4]);
+ CU_ASSERT(ret == 0);
+
+ ret = sepol_list_append(list, &nums[5]);
+ CU_ASSERT(ret == 0);
+
+ ret = sepol_list_prepend(list, &nums[1]);
+ CU_ASSERT(ret == 0);
+
+ ret = sepol_list_begin(list, iter);
+ CU_ASSERT(ret == 0);
+ ret = sepol_iter_forward(iter, 1);
+ CU_ASSERT(ret == 0);
+
+ ret = sepol_list_insert(list, iter, &nums[2]);
+ CU_ASSERT(ret == 0);
+
+ ret = sepol_list_begin(list, iter);
+ CU_ASSERT(ret == 0);
+ ret = sepol_list_insert(list, iter, &nums[0]);
+ CU_ASSERT(ret == 0);
+
+ ret = sepol_list_begin(list, iter);
+ CU_ASSERT(ret == 0);
+ ret = sepol_iter_forward(iter, 3);
+ CU_ASSERT(ret == 0);
+
+ ret = sepol_list_insert(list, iter, &nums[3]);
+ CU_ASSERT(ret == 0);
+
+ ret = sepol_list_begin(list, iter);
+ CU_ASSERT(ret == 0);
+ i = 0;
+ while (ret == SEPOL_OK) {
+ num = (int*)sepol_iter_get_data(iter);
+ CU_ASSERT(*num == i);
+ i++;
+ ret = sepol_iter_next(iter);
+ }
+ CU_ASSERT(i == 6);
+ CU_ASSERT(ret == SEPOL_ITERSTOP);
+
+ ret = sepol_list_end(list, iter);
+ CU_ASSERT(ret == 0);
+ i = 5;
+ while (ret == SEPOL_OK) {
+ num = (int*)sepol_iter_get_data(iter);
+ CU_ASSERT(*num == i);
+ i--;
+ ret = sepol_iter_prev(iter);
+ }
+ CU_ASSERT(i == -1);
+ CU_ASSERT(ret == SEPOL_ITERSTOP);
+
+ ret = sepol_list_end(list, iter);
+ CU_ASSERT(ret == 0);
+ ret = sepol_iter_prev(iter);
+ CU_ASSERT(ret == 0);
+ num = (int*)sepol_iter_get_data(iter);
+ CU_ASSERT(*num == 4);
+
+
+ sepol_iter_destroy(iter);
+ sepol_list_destroy(list);
+}
+
+int list_add_tests(CU_pSuite suite)
+{
+ if (NULL == CU_add_test(suite, "test_list_create", test_list_create)) {
+ return -1;
+ }
+
+ if (NULL == CU_add_test(suite, "test_list",
+ test_list)) {
+ return -1;
+ }
+
+ return 0;
+}
diff -r 20ff5c9a577b libsepol/tests/test-list.h
--- a/libsepol/tests/test-list.h Tue Jan 16 15:50:54 2007 -0500
+++ b/libsepol/tests/test-list.h Tue Jan 16 16:04:16 2007 -0500
@@ -0,0 +1,12 @@
+/* Author : Karl MacMillan <kmacmillan@mentalrootkit.com> */
+
+#ifndef __test_list_h__
+#define __test_list_h__
+
+#include <CUnit/Basic.h>
+
+int list_test_init(void);
+int list_test_cleanup(void);
+int list_add_tests(CU_pSuite suite);
+
+#endif
next reply other threads:[~2007-01-16 21:10 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-01-16 21:10 Karl MacMillan [this message]
2007-01-16 22:24 ` [RFC] Add list and iter data types to libsepol Karl MacMillan
2007-01-17 12:15 ` Stephen Smalley
2007-01-17 15:16 ` Karl MacMillan
2007-01-18 15:47 ` Stephen Smalley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=45AD3F51.9070005@mentalrootkit.com \
--to=kmacmillan@mentalrootkit.com \
--cc=selinux@tycho.nsa.gov \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.