Commit e2999c7

mo khan <mo.khan@gmail.com>
2020-07-05 20:56:21
Add documentation
1 parent 06e99f0
src/01/05/doubly_linked_list.c
@@ -1,7 +1,15 @@
 #include "doubly_linked_list.h"
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
+/**
+ * The equivalent of a constructor
+ * to initialize a new node in a doubly linked list.
+ *
+ * @param data The data to initialize the head node with.
+ * @return new Node bound to the data specified
+ */
 Node *initialize(int data) {
   Node *node = malloc(sizeof(Node));
   node->data = data;
@@ -10,21 +18,43 @@ Node *initialize(int data) {
   return node;
 }
 
-Node *add(Node *head, int data) {
-  Node *tail;
+/**
+ * Returns the tail of the list.
+ *
+ * @param head The head of the linked list
+ * @return The tail of the linked list
+ */
+Node *tail(Node *head) {
   Node *tmp = head;
-
   while (tmp) {
     if (!tmp->next)
       break;
     tmp = tmp->next;
   }
-  tail = tmp;
-  tail->next = initialize(data);
-  tail->next->prev = tail;
-  return tail->next;
+  return tmp;
+}
+
+/**
+ * Adds data to the tail of a doubly linked list.
+ *
+ * @param head The head of the doubly linked list
+ * @param data The data to append to the list
+ * @return Returns the new node.
+ */
+Node *add(Node *head, int data) {
+  Node *t = tail(head);
+  t->next = initialize(data);
+  t->next->prev = t;
+  return t->next;
 }
 
+/**
+ * Returns a specific node in the list by index starting from 0.
+ *
+ * @param from The node to start scanning from.
+ * @param index The zero based index of the node to retrieve.
+ * @return The node at the specified index.
+ */
 Node *get(Node *from, int index) {
   if (!from || index < 0)
     return NULL;
@@ -36,6 +66,12 @@ Node *get(Node *from, int index) {
   return from;
 }
 
+/**
+ * Returns the number of items in the linked list.
+ *
+ * @param head The head of the linked list
+ * @return The number of items in the list.
+ */
 static int size(Node *head) {
   int i = 0;
   for (Node *tmp = head; tmp && tmp != NULL; tmp = tmp->next)
@@ -43,6 +79,12 @@ static int size(Node *head) {
   return i;
 }
 
+/**
+ * Assigns the next pointer of a node.
+ *
+ * @param self The node struct to alter.
+ * @param other The other node to point to.
+ */
 static void assign_next(Node *self, Node *other) {
   if (self)
     self->next = other;
@@ -51,6 +93,12 @@ static void assign_next(Node *self, Node *other) {
     other->prev = self;
 }
 
+/**
+ * Assigns the previous pointer of a node.
+ *
+ * @param self The node struct to alter.
+ * @param other The other node to point to.
+ */
 static void assign_prev(Node *self, Node *other) {
   if (self)
     self->prev = other;
@@ -59,6 +107,12 @@ static void assign_prev(Node *self, Node *other) {
     other->next = self;
 }
 
+/**
+ * Reverses a linked list.
+ *
+ * @param head The head of the linked list.
+ * @return The new head of the linked list.
+ */
 Node *reverse(Node *head) {
   Node *tmp = NULL;
   Node *current = head;
@@ -72,24 +126,59 @@ Node *reverse(Node *head) {
   return tmp ? tmp->prev : head;
 }
 
-static void print(Node *node) {
+/**
+ * Generates a string representation of the Node usable for printing to stdout
+ *
+ * @param node The node to represent as a string
+ * @return The string that represents the node
+ */
+char *to_s(Node *node) {
+  const int buffer_size = 32;
+  char *buffer = malloc(buffer_size);
+  memset(buffer, buffer_size, '\0');
+
   if (node->prev && node->next)
-    printf("(%d<%d>%d)", node->prev->data, node->data, node->next->data);
+    snprintf(buffer, buffer_size, "(%d<%d>%d) ", node->prev->data, node->data, node->next->data);
   else if (node->next)
-    printf("(nil<%d>%d)", node->data, node->next->data);
+    snprintf(buffer, buffer_size, "(nil<%d>%d) ", node->data, node->next->data);
   else
-    printf("(%d<%d>nil)", node->prev->data, node->data);
+    snprintf(buffer, buffer_size, "(%d<%d>nil) ", node->prev->data, node->data);
+  return buffer;
 }
 
-void inspect(Node *node) {
-  if (!node)
-    return;
+/**
+ * Prints the previous, data and next pointers for a node
+ *
+ * @param node The node to print
+ */
+static void print(Node *node) {
+  char *message = to_s(node);
+  printf("%s", message);
+  free(message);
+}
 
-  printf("[ ");
-  while (node) {
-    print(node);
-    printf(" ");
-    node = node->next;
+/**
+ * Iterates through each node in a linked list.
+ *
+ * @param self The node to start iterating from.
+ * @param block The callback function to invoke on each node.
+ */
+void each(Node *self, Visitor block) {
+  Node *tmp = self;
+
+  while (tmp) {
+    block(tmp);
+    tmp = tmp->next;
   }
+}
+
+/**
+ * Renders a visual output of a full linked list.
+ *
+ * @param node The head of the linked list
+ */
+void inspect(Node *node) {
+  printf("[ ");
+  each(node, &print);
   printf("]\n");
 }
src/01/05/doubly_linked_list.h
@@ -5,6 +5,7 @@ struct node {
 };
 
 typedef struct node Node;
+typedef void (Visitor)(Node *);
 
 Node *initialize(int data);
 Node *add(Node *head, int data);
src/01/05/README.md
@@ -41,8 +41,8 @@ clang build/doubly_linked_list.o build/main.o -o build/program
 Before:
         [ (nil<0>0) (0<0>1) (0<1>2) (1<2>3) (2<3>4) (3<4>5) (4<5>6) (5<6>7) (6<7>8) (7<8>9) (8<9>nil) ]
         Reversing...
-        After:
-                [ (nil<9>8) (9<8>7) (8<7>6) (7<6>5) (6<5>4) (5<4>3) (4<3>2) (3<2>1) (2<1>0) (1<0>0) (0<0>nil) ]
+After:
+        [ (nil<9>8) (9<8>7) (8<7>6) (7<6>5) (6<5>4) (5<4>3) (4<3>2) (3<2>1) (2<1>0) (1<0>0) (0<0>nil) ]
 ```
 
 ## Discussion