summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Angelacos <nangel@alpinelinux.org>2008-05-12 22:01:20 +0000
committerNathan Angelacos <nangel@alpinelinux.org>2008-05-12 22:01:20 +0000
commitbb899c9dda1b0e7d317b89ee5bdca96b3d499c4d (patch)
treef1f5bb52778093248719432c9f5a75b4564391d8
parentb91a4a4d1ac83161e78645a987fe168eb1df220b (diff)
downloadhaserl-bb899c9dda1b0e7d317b89ee5bdca96b3d499c4d.tar.bz2
haserl-bb899c9dda1b0e7d317b89ee5bdca96b3d499c4d.tar.xz
llist from busybox
-rw-r--r--src/llist.c123
-rw-r--r--src/llist.h9
-rw-r--r--src/xmalloc.c45
-rw-r--r--src/xmalloc.h8
-rw-r--r--tests/utest_llist.c55
5 files changed, 235 insertions, 5 deletions
diff --git a/src/llist.c b/src/llist.c
new file mode 100644
index 0000000..48d01fa
--- /dev/null
+++ b/src/llist.c
@@ -0,0 +1,123 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * linked list helper functions.
+ *
+ * Copyright (C) 2003 Glenn McGrath
+ * Copyright (C) 2005 Vladimir Oleynik
+ * Copyright (C) 2005 Bernhard Fischer
+ * Copyright (C) 2006 Rob Landley <rob@landley.net>
+ *
+ * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
+ *
+ * haserl uses busybox's libbb functions where appropriate because
+ * a (very long-term) goal is to get it to be a bb applet.
+ */
+
+#include "llist.h"
+
+/* Add data to the start of the linked list. */
+void
+llist_add_to (llist_t ** old_head, void *data)
+{
+ llist_t *new_head = xmalloc (sizeof (llist_t));
+
+ new_head->data = data;
+ new_head->link = *old_head;
+ *old_head = new_head;
+}
+
+/* Add data to the end of the linked list. */
+void
+llist_add_to_end (llist_t ** list_head, void *data)
+{
+ llist_t *new_item = xmalloc (sizeof (llist_t));
+
+ new_item->data = data;
+ new_item->link = NULL;
+
+ if (!*list_head)
+ *list_head = new_item;
+ else
+ {
+ llist_t *tail = *list_head;
+
+ while (tail->link)
+ tail = tail->link;
+ tail->link = new_item;
+ }
+}
+
+/* Remove first element from the list and return it */
+void *
+llist_pop (llist_t ** head)
+{
+ void *data, *next;
+
+ if (!*head)
+ return NULL;
+
+ data = (*head)->data;
+ next = (*head)->link;
+ free (*head);
+ *head = next;
+
+ return data;
+}
+
+/* Unlink arbitrary given element from the list */
+void
+llist_unlink (llist_t ** head, llist_t * elm)
+{
+ llist_t *crt;
+
+ if (!(elm && *head))
+ return;
+
+ if (elm == *head)
+ {
+ *head = (*head)->link;
+ return;
+ }
+
+ for (crt = *head; crt; crt = crt->link)
+ {
+ if (crt->link == elm)
+ {
+ crt->link = elm->link;
+ return;
+ }
+ }
+}
+
+/* Recursively free all elements in the linked list. If freeit != NULL
+ * call it on each datum in the list */
+void
+llist_free (llist_t * elm, void (*freeit) (void *data))
+{
+ while (elm)
+ {
+ void *data = llist_pop (&elm);
+
+ if (freeit)
+ freeit (data);
+ }
+}
+
+#ifdef UNUSED
+/* Reverse list order. */
+llist_t *
+llist_rev (llist_t * list)
+{
+ llist_t *rev = NULL;
+
+ while (list)
+ {
+ llist_t *next = list->link;
+
+ list->link = rev;
+ rev = list;
+ list = next;
+ }
+ return rev;
+}
+#endif
diff --git a/src/llist.h b/src/llist.h
index 03c4e88..0f75942 100644
--- a/src/llist.h
+++ b/src/llist.h
@@ -1,9 +1,8 @@
/*
- * Linked List functions, should be api compatible with Busybox
- * These are the function declarations from the libbb.h file
+ * Linked List functions from lib busybox
*/
-#ifndef _LLIST_H
-#define _LLIST_H 1
+#ifndef X_LLIST_H
+#define X_LLIST_H 1
typedef struct llist_t {
char *data;
@@ -17,4 +16,4 @@ void llist_unlink(llist_t **head, llist_t *elm);
void llist_free(llist_t *elm, void (*freeit)(void *data));
-#endif /* LLIST_H */
+#endif /* X_LLIST_H */
diff --git a/src/xmalloc.c b/src/xmalloc.c
new file mode 100644
index 0000000..ced7820
--- /dev/null
+++ b/src/xmalloc.c
@@ -0,0 +1,45 @@
+/* --------------------------------------------------------------------------
+ * xmalloc definition - allocate or die
+ * Copyright (c) 2008 Nathan Angelacos (nangel@users.sourceforge.net)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License, version 2, as published
+ * by the Free Software Foundation.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ ------------------------------------------------------------------------- */
+
+#include <stdlib.h>
+
+void *
+xmalloc (size_t size)
+{
+ void *buf;
+ buf = malloc (size);
+ if ((buf == NULL) && (size > 0))
+ {
+ abort ();
+ }
+ return buf;
+}
+
+
+void *
+xrealloc (void *buf, size_t size)
+{
+ buf = realloc (buf, size);
+ if ((buf == NULL) && (size > 0))
+ {
+ abort ();
+ }
+ return buf;
+}
diff --git a/src/xmalloc.h b/src/xmalloc.h
new file mode 100644
index 0000000..dd26560
--- /dev/null
+++ b/src/xmalloc.h
@@ -0,0 +1,8 @@
+#ifndef XMALLOC_H
+#define XMALLOC_H 1
+
+void *xmalloc (size_t size);
+void *xrealloc (void *buf, size_t size);
+
+#endif /* XMALLOC_H */
+
diff --git a/tests/utest_llist.c b/tests/utest_llist.c
new file mode 100644
index 0000000..1c2a570
--- /dev/null
+++ b/tests/utest_llist.c
@@ -0,0 +1,55 @@
+/* llist test framework */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "../src/llist.h"
+#include "../src/xmalloc.h"
+#include "minunit.h"
+
+int tests_run = 0;
+
+void * xmalloc=malloc;
+void * xrealloc=realloc;
+
+
+void llist_add_to(llist_t **old_head, void *data);
+void llist_add_to_end(llist_t **list_head, void *data);
+void *llist_pop(llist_t **elm);
+void llist_unlink(llist_t **head, llist_t *elm);
+void llist_free(llist_t *elm, void (*freeit)(void *data));
+
+
+
+
+char *test_lowercase() {
+ char source[] = "This is a Test!";
+ int result;
+
+ lowercase(source);
+ result=memcmp("this is a test!", source, strlen(source));
+
+ mu_assert("lowercase failed",result == 0);
+ return 0;
+ }
+
+
+char *all_tests() {
+ mu_run_test(test_lowercase);
+ return 0;
+ }
+
+int main(int argc, char **argv) {
+ char *result = all_tests();
+ printf ("%d\n", (int) result);
+ if (result != 0) {
+ printf("%s\n", result);
+ }
+ else {
+ printf("ALL TESTS PASSED\n");
+ }
+ printf("Tests run: %d\n", tests_run);
+
+ return result != 0;
+ }
+