commit f66a063dcd6f7dbbdc9c088e43b14f8e11ec0416
parent 51df4f1dd977ef7215a9a298f176a88b0a70bb4c
Author: Matsuda Kenji <info@mtkn.jp>
Date: Wed, 11 Jan 2023 10:46:19 +0900
add test
Diffstat:
4 files changed, 226 insertions(+), 1 deletion(-)
diff --git a/ex9/list.c b/ex9/list.c
@@ -16,7 +16,8 @@ struct List *
laddfront(struct List *p, void *item)
{
if (item == NULL) {
- fprintf(stderr, "laddfront: Error. Item is NULL\n");
+ // TODO: should print some message ??
+ //fprintf(stderr, "laddfront: Error. Item is NULL\n");
return NULL;
}
@@ -155,8 +156,43 @@ __lqsort(struct List *p, struct List *tail, int (* cmp)(void *, void *))
void
lswap(struct List *p, struct List *q)
{
+ if (p == NULL || q == NULL)
+ return;
void *tmp;
tmp = p->item;
p->item = q->item;
q->item = tmp;
}
+
+/*
+ * Leqa() returns 1 if two Lists are identicall, 0 if not.
+ * Only checks the address of each items.
+ */
+int
+leqa(struct List *p, struct List *q)
+{
+ for (;p != NULL && q != NULL; p = p->next, q = q->next) {
+ if (p->item != q->item)
+ return 0;
+ }
+ if (p == NULL && q == NULL)
+ return 1;
+ return 0;
+}
+
+/*
+ * Leqi() returns 1 if two Lists are identicall, 0 if not.
+ * Compares each items with eq().
+ */
+int
+leqi(struct List *p, struct List *q, int (*eq)(void *, void*))
+{
+ for (;p != NULL && q != NULL; p = p->next, q = q->next) {
+ if (!eq(p->item, q->item))
+ return 0;
+ }
+ if (p == NULL && q == NULL)
+ return 1;
+ return 0;
+}
+
diff --git a/ex9/list.h b/ex9/list.h
@@ -5,6 +5,8 @@ void lprint(struct List *p, void (* pfnc)(void *));
int lbsort(struct List *p, int (* cmp)(void *, void *));
int lqsort(struct List *p, int (* cmp)(void *, void *));
void lswap(struct List *p, struct List *q);
+int leqa(struct List *p, struct List *q);
+int leqi(struct List *p, struct List *q, int (*eq)(void *, void *));
/* Linked list. An empty list must be initialized with NULL. */
struct List {
diff --git a/ex9/test/a.out b/ex9/test/a.out
Binary files differ.
diff --git a/ex9/test/list_t.c b/ex9/test/list_t.c
@@ -0,0 +1,187 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "../list.h"
+
+struct Item {
+ int id;
+};
+
+/* utils for testing */
+void iprint(struct Item *);
+struct Item* icreate(int);
+void ifree(struct Item *);
+int icmp(struct Item *, struct Item *);
+int ieq(struct Item *, struct Item *);
+struct List * lcreate_from_array(int nums[], int n);
+void aswap(int nums[], int i, int j);
+
+/* tests */
+void test_laddfront(void);
+void test_lswap(void);
+
+void
+iprint(struct Item *p)
+{
+ printf("[%d]", p->id);
+}
+
+struct Item*
+icreate(int id)
+{
+ struct Item *p;
+ p = (struct Item *)malloc(sizeof(struct Item));
+ p->id = id;
+ return p;
+}
+
+void
+ifree(struct Item *p)
+{
+ free(p);
+}
+
+int
+icmp(struct Item *p, struct Item *q)
+{
+ if (p->id < q->id)
+ return -1;
+ else if (p->id == q->id)
+ return 0;
+ else
+ return 1;
+}
+
+int
+ieq(struct Item *p, struct Item *q)
+{
+ return !icmp(p, q);
+}
+
+struct List *
+lcreate_from_array(int nums[], int n)
+{
+ struct List *p, *tmp;
+ p = NULL;
+ for (int i = n - 1; i >= 0; i--) {
+ tmp = laddfront(p, icreate(nums[i]));
+ if (tmp == NULL) {
+ fprintf(stderr, "lcreate_from_array(): Fatal. Laddfront() failed.\n");
+ exit(1);
+ }
+ p = tmp;
+ }
+ return p;
+}
+
+void
+aswap(int nums[], int i, int j)
+{
+ int tmp;
+ tmp = nums[i];
+ nums[i] = nums[j];
+ nums[j] = tmp;
+}
+
+
+void
+test_laddfront(void)
+{
+ int n = 3;
+ int num[n];
+ struct Item *item[n];
+ struct List *p = NULL, *tmp;
+
+ if ((tmp = laddfront(p, NULL)) != NULL)
+ fprintf(stderr, "test_laddfront: Adding NULL item should return"
+ "NULL\n");
+
+ for (int i = 0; i < n; i++)
+ item[i] = icreate(num[i]);
+
+ for (int i = 0; i < n; i++) {
+ if ((tmp = laddfront(p, item[i])) == NULL)
+ fprintf(stderr, "test_laddfront: Adding item failed.\n");
+ p = tmp;
+ }
+ lfreei(p, (void (*)(void *))&ifree);
+}
+
+/*
+ * Test for lswap().
+ * Assume that laddfront, leqa, leqi work correctly.
+ */
+void
+test_lswap(void)
+{
+ struct List *p = NULL, *q = NULL, *tmp;
+
+ /* test for NULL List. */
+ lswap(p, p);
+ if (p != NULL)
+ fprintf(stderr, "test_lswap: Test for NULL List failed.\n");
+
+ /* test for one element List. */
+ struct Item *item;
+ item = icreate(0);
+
+ tmp = laddfront(p, item);
+ if (tmp == NULL) {
+ fprintf(stderr, "test_lswap: Fatal. laddfront() failed.\n");
+ exit(1);
+ }
+ p = tmp;
+ tmp = laddfront(q, item);
+ if (tmp == NULL) {
+ fprintf(stderr, "test_lswap: Fatal. laddfront() failed.\n");
+ exit(1);
+ }
+ q = tmp;
+ lswap(p, p);
+ if (! leqa(p, q))
+ fprintf(stderr, "test_lswap: Test for one element List failed.\n");
+ lfree(p);
+ lfree(q);
+ ifree(item);
+
+ /* test for random numbers */
+ /* swaps every pairs with lswap and aswap, then checks both are same */
+ struct List *li, *lj;
+ int i, j;
+ int lmin = 5;
+ int lmax = 15;
+ p = q = NULL;
+
+ int n = (unsigned int)rand() % (lmax - lmin) + lmin;
+ assert(lmin <= n && n < lmax);
+ int nums[n];
+
+ for (int i = 0; i < n; i++) {
+ nums[i] = rand();
+ }
+ p = lcreate_from_array(nums, n);
+ for (i = 0, li = p; i < n && li != NULL; i++, li = li->next) {
+ for (j = 0, lj = p; j < n && lj != NULL; j++, lj = lj->next) {
+ lswap(li, lj);
+ aswap(nums, i, j);
+ q = lcreate_from_array(nums, n);
+ if (!leqi(p, q, (int (*)(void *, void*))&ieq))
+ fprintf(stderr, "test_lswap: Test for longer List failed.\n");
+ lfreei(q, (void (*))(void *)&ifree);
+ }
+ }
+ if (i != j)
+ fprintf(stderr, "test_lswap: Index mismatch.\n");
+
+ lfreei(p, (void (*))(void *)&ifree);
+}
+
+int
+main(void)
+{
+ test_laddfront();
+ test_lswap();
+
+ return 0;
+}