commit 92deabc9b78c9b53f79907ef5330d8a588de928f
parent 8695f15c06360bb9d2562ea596570c3884da4341
Author: Matsuda Kenji <info@mtkn.jp>
Date: Tue, 10 Jan 2023 07:31:59 +0900
add error messages
Diffstat:
4 files changed, 159 insertions(+), 35 deletions(-)
diff --git a/ex9/list.c b/ex9/list.c
@@ -4,97 +4,152 @@
#include "list.h"
-static void __lqsort(struct List *lp, struct List *tail,
+static int __lqsort(struct List *p, struct List *tail,
int (* cmp)(void *, void *));
-static void __lprint(struct List *lp, struct List *tail, void (* pfnc)(void *));
+static void __lprint(struct List *p, struct List *tail, void (* pfnc)(void *));
+/*
+ * Laddfront() adds item in front of List p.
+ * Returns NULL if error occured.
+ */
struct List *
-addfront(struct List *lp, void *item)
+laddfront(struct List *p, void *item)
{
+ if (item == NULL) {
+ fprintf(stderr, "laddfront: Error. Item is NULL\n");
+ return NULL;
+ }
+
struct List *newlp;
- if((newlp = (struct List *)malloc(sizeof(struct List))) == NULL)
+ if((newlp = (struct List *)malloc(sizeof(struct List))) == NULL) {
+ fprintf(stderr, "laddfront: Error. Could not allocate memory.\n");
return NULL;
+ }
newlp->item = item;
- newlp->next = lp;
+ newlp->next = p;
return newlp;
}
+/*
+ * Lfree() frees List *p. Its items should be freed elsewhere.
+ */
+void
+lfree(struct List *p)
+{
+ struct List *q;
+ for (q = p; q != NULL; q = p) {
+ p = q->next;
+ free(q);
+ }
+}
+
+/*
+ * Lfreei() frees List *p. Its items are freed using ifree().
+ */
void
-lprint(struct List *lp, void (* pfnc)(void *))
+lfreei(struct List *p, void (* ifree)(void *))
{
- for (;lp != NULL; lp = lp->next) {
- (*pfnc)(lp->item);
- printf("%s", lp->next == NULL ? "\n" : "->");
+ struct List *q;
+ for (q = p; q != NULL; q = p) {
+ p = q->next;
+ ifree(q->item);
+ free(q);
}
}
void
-__lprint(struct List *lp, struct List *tail, void (* pfnc)(void *))
+lprint(struct List *p, void (* pfnc)(void *))
+{
+ __lprint(p, NULL, pfnc);
+}
+
+void
+__lprint(struct List *p, struct List *tail, void (* pfnc)(void *))
{
- if (lp == NULL) {
+ if (p == NULL) {
printf("\n");
}
- for (;lp != tail; lp = lp->next) {
- (*pfnc)(lp->item);
- printf("%s", lp->next == tail ? "\n" : "->");
+ for (;p != tail && p != NULL; p = p->next) {
+ if (p->item == NULL) {
+ fprintf(stderr, "__lprint: Error. Item is NULL\n");
+ return;
+ }
+ (*pfnc)(p->item);
+ printf("%s", p->next == tail ? "\n" : "->");
+ }
+ if (p != tail) {
+ fprintf(stderr, "__lprint: Warning. Tail not found in the list.\n");
}
}
/*
- * Bubble sort
+ * Bubble sort. returns -1 if error occured, 0 if succeed.
*/
-void
+int
lbsort(struct List *p, int (* cmp)(void *, void *))
{
struct List *q;
for (;p != NULL && p->next != NULL; p = p->next) {
for (q = p->next; q != NULL; q = q->next) {
+ if (p->item == NULL || q->item == NULL) {
+ fprintf(stderr, "lbsort: Error. List without item.\n");
+ return -1;
+ }
if (cmp(p->item, q->item) > 0) {
lswap(p, q);
}
}
}
+ return 0;
}
/*
* Quick sort
- * Tail is the next of the last item in List *p.
- * Tail can be NULL;
+ * Lqsort() sorts entire List p, according to the results of cmp().
+ * __lqsort() sorts the List from p to the item before tail.
+ * Tail can be NULL. This case __lqsort() sorts entire List.
+ * Returns 0 if succeed, -1 if error occured.
*/
-void
+int
lqsort(struct List *p, int (* cmp)(void *, void *))
{
- __lqsort(p, NULL, cmp);
+ return __lqsort(p, NULL, cmp);
}
-static void
-__lqsort(struct List *lp, struct List *tail, int (* cmp)(void *, void *))
+static int
+__lqsort(struct List *p, struct List *tail, int (* cmp)(void *, void *))
{
- if (lp == tail || lp->next == tail)
- return;
+ if (p == tail || p->next == tail)
+ return 0;
struct List *pivot, *q, *last;
int i;
/* select the pivot randomly */
- for (i = 0, q = lp; q != tail; q = q->next) {
+ for (i = 0, q = p; q != tail; q = q->next) {
if (rand() % ++i == 0)
pivot = q;
}
- lswap(lp, pivot);
- last = lp;
- for (q = lp->next; q != tail; q = q->next) {
- if (cmp(lp->item, q->item) > 0) {
+ lswap(p, pivot);
+ last = p;
+ for (q = p->next; q != tail; q = q->next) {
+ if (p->item == NULL || q->item == NULL) {
+ fprintf(stderr, "lbsort: Error. List without item.\n");
+ return -1;
+ }
+ if (cmp(p->item, q->item) > 0) {
last = last->next;
lswap(last, q);
}
}
- lswap(lp, last);
+ lswap(p, last);
__lqsort(last->next, tail, cmp);
- __lqsort(lp, last, cmp);
+ __lqsort(p, last, cmp);
+
+ return 0;
}
void
diff --git a/ex9/list.h b/ex9/list.h
@@ -1,9 +1,12 @@
-struct List * addfront(struct List *lp, void *item);
-void lprint(struct List *lp, void (* pfnc)(void *));
-void lbsort(struct List *p, int (* cmp)(void *, void *));
-void lqsort(struct List *p, int (* cmp)(void *, void *));
+struct List * laddfront(struct List *p, void *item);
+void lfree(struct List *p);
+void lfreei(struct List *p, void (* ifree)(void *));
+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);
+/* Linked list. An empty list must be initialized with NULL. */
struct List {
struct List *next;
void *item;
diff --git a/ex9/test/a.out b/ex9/test/a.out
Binary files differ.
diff --git a/ex9/test/lits_t.c b/ex9/test/lits_t.c
@@ -0,0 +1,66 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "../list.h"
+
+struct Item {
+ int id;
+};
+
+void iprint(struct Item *);
+struct Item* icreate(int);
+void ifree(struct Item *);
+int icmp(struct Item *, struct Item *);
+
+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
+main(void)
+{
+ struct List *p = NULL, *q = NULL;
+
+ for (int i = 0; i < 10; i++) {
+ if ((q = laddfront(p, icreate(random()%100))) == NULL) {
+ // Maybe this is not the error of laddfront.
+ fprintf(stderr, "addfront error.\n");
+ } else {
+ p = q;
+ }
+ }
+ lprint(p, (void (*)(void *))&iprint);
+ lqsort(p, (int (*)(void *, void *))&icmp);
+ lprint(p, (void (*)(void *))&iprint);
+ lfreei(p, (void (*)(void *))&ifree);
+
+ return 0;
+}