[ekg2-commit] r4070 - trunk/contrib: +trunk/contrib/testcase_for_remove_iter.c
SVN commit
svn w toxygen.net
Wto, 8 Lip 2008, 19:08:03 CEST
Author: darkjames
Date: 2008-07-08 19:08:03 +0200 (Tue, 08 Jul 2008)
New Revision: 4070
Added:
trunk/contrib/testcase_for_remove_iter.c
Log:
testcase for __DYNSTUFF_LIST_REMOVE_ITER()
Added: trunk/contrib/testcase_for_remove_iter.c
===================================================================
--- trunk/contrib/testcase_for_remove_iter.c (rev 0)
+++ trunk/contrib/testcase_for_remove_iter.c 2008-07-08 17:08:03 UTC (rev 4070)
@@ -0,0 +1,132 @@
+/* short note (in Polish, sorry)
+ *
+ * testcase majacy na celu sprawdzenie czy __DYNSTUFF_LIST_REMOVE_ITER()
+ * dziala poprawnie przy zwalnianiu pierwszych elementow listy.
+ *
+ * Powinno byc troche inaczej, w innym .o zeby kompilator nie mogl sobie tego zoptymalizowac.
+ * ale dla -O0 ... -O3 dziala poprawnie,
+ *
+ * prawidlowy output:
+ * f == 0x602070: 40, 30, 20, 10,
+ * f == 0x602050: 30, 20, 10,
+ * f == 0x602030: 20, 10,
+ * f == 0x602010: 10,
+ * f == (nil):
+ *
+ * jesli twoj kompilator dla pewnych wartosci -O lub nie korzystasz z gcc, lub korzystach z innych kosmicznych flag kompilatora
+ * generuje nieprawidlowy kod, ktory generuje nieprawidlowy output (adresy moga byc rozne :>)
+ * daj info.
+ *
+ * wiechu chcial aby to bylo testowane w czasie ./configure moze kiedys.
+ * Na razie wrzucam do contrib/
+ *
+ * Ogolnie korzystamy z faktu, ze w C:
+ * - strukturka->pierwszy_element_strukturki == *(strukturka + 0) == *strukturka
+ * - *(&foo) == foo
+ */
+
+/* __DYNSTUFF_LIST_REMOVE_ITER() jest ogolnie b. fajne, i b. przydatne. */
+/* thx goes to wiechu. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define xfree free
+
+#include <ekg/dynstuff_inline.h>
+
+#ifdef DYNSTUFF_USE_LIST3
+#include <errno.h>
+
+/* stuff copied from dynstuff.c */
+
+void *list_add_beginning3(list_t *list, list_t new) {
+ if (!list) {
+ errno = EFAULT;
+ return NULL;
+ }
+
+ new->next = *list;
+ *list = new;
+
+ return new;
+}
+
+void *list_remove3i(list_t *list, list_t elem, void (*func)(list_t data)) {
+ list_t tmp, last = NULL;
+ void *ret = NULL;
+
+ if (!list) {
+ errno = EFAULT;
+ return ret;
+ }
+
+ tmp = *list;
+ if (tmp && tmp == elem) {
+ *list = tmp->next;
+ ret = list;
+ } else {
+ for (; tmp && tmp != elem; tmp = tmp->next)
+ last = tmp;
+ if (!tmp) {
+ errno = ENOENT;
+ return ret;
+ }
+ last->next = tmp->next;
+ ret = last;
+ }
+
+ if (func)
+ func(tmp);
+ xfree(tmp);
+
+ return ret;
+}
+
+#endif
+
+typedef struct foo {
+ struct foo *next;
+ int val;
+} foo;
+
+foo *foos;
+
+void do_nothing(foo *f) { }
+
+__DYNSTUFF_LIST_ADD_BEGINNING(foos, foo, NULL);
+__DYNSTUFF_LIST_REMOVE_ITER(foos, foo, do_nothing);
+
+foo *nowy_element(int val) {
+ foo *tmp = malloc(sizeof(foo));
+
+ tmp->val = val;
+
+ foos_add(tmp);
+ return tmp;
+}
+
+void print(foo *f) {
+ printf("f == %p: ", f);
+ for (; f; f = f->next)
+ printf("%d, ", f->val);
+ printf("\n");
+}
+
+int main() {
+ foo *f;
+
+ nowy_element(10);
+ nowy_element(20);
+ nowy_element(30);
+ nowy_element(40);
+
+ for (f = foos; f; f = f->next) {
+ print(foos);
+
+ f = foos_removei(f);
+ }
+ print(foos);
+ return 0;
+}
+
Więcej informacji o liście dyskusyjnej ekg2-commit