xlib_playground

Xlib playground for experiments.
Log | Files | Refs

commit f66a063dcd6f7dbbdc9c088e43b14f8e11ec0416
parent 51df4f1dd977ef7215a9a298f176a88b0a70bb4c
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Wed, 11 Jan 2023 10:46:19 +0900

add test

Diffstat:
Mex9/list.c | 38+++++++++++++++++++++++++++++++++++++-
Mex9/list.h | 2++
Mex9/test/a.out | 0
Aex9/test/list_t.c | 187+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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; +}