Skip to content

Commit

Permalink
Merge pull request #106 from Galfurian/fix-memory-error
Browse files Browse the repository at this point in the history
- Improved comments and error checking to memory related files.
- Improved comments and error checking to list_head.
  • Loading branch information
Galfurian authored Sep 30, 2024
2 parents 39297b2 + b409d6a commit 35e59ce
Show file tree
Hide file tree
Showing 12 changed files with 2,608 additions and 846 deletions.
52 changes: 35 additions & 17 deletions libc/inc/sys/list_head.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@

/// @brief Structure used to implement the list_head data structure.
typedef struct list_head {
/// @brief The previous element.
struct list_head *prev;
/// @brief The subsequent element.
struct list_head *next;
struct list_head *prev; ///< The previous element.
struct list_head *next; ///< The subsequent element.
} list_head;

/// @brief Get the struct for this entry.
Expand Down Expand Up @@ -66,6 +64,7 @@ typedef struct list_head {
/// @param head The head of your list.
static inline void list_head_init(list_head *head)
{
assert(head && "Variable head is NULL."); // Ensure head is not NULL
head->next = head->prev = head;
}

Expand All @@ -74,7 +73,7 @@ static inline void list_head_init(list_head *head)
/// @return 1 if empty, 0 otherwise.
static inline int list_head_empty(const list_head *head)
{
assert(head && "Variable head is NULL.");
assert(head && "Variable head is NULL."); // Ensure head is not NULL
return head->next == head;
}

Expand All @@ -83,6 +82,8 @@ static inline int list_head_empty(const list_head *head)
/// @return the size of the list.
static inline unsigned list_head_size(const list_head *head)
{
assert(head && "Variable head is NULL."); // Ensure head is not NULL

unsigned size = 0;
if (!list_head_empty(head)) {
list_for_each_decl(it, head) size += 1;
Expand All @@ -91,12 +92,15 @@ static inline unsigned list_head_size(const list_head *head)
}

/// @brief Insert the new entry after the given location.
/// @param new_entry the new element we want to insert.
/// @param location the element after which we insert.
/// @param new_entry The new element we want to insert.
/// @param location The element after which we insert.
static inline void list_head_insert_after(list_head *new_entry, list_head *location)
{
assert(new_entry && "Variable new_entry is NULL.");
assert(location && "Variable location is NULL.");
assert(new_entry && "Variable new_entry is NULL."); // Check for NULL new_entry
assert(location && "Variable location is NULL."); // Check for NULL location
assert(location->prev && "Variable location->prev is NULL."); // Check location is valid
assert(location->next && "Variable location->next is NULL."); // Check location is valid

// We store the old `next` element.
list_head *old_next = location->next;
// We insert our element.
Expand Down Expand Up @@ -132,10 +136,12 @@ static inline void list_head_insert_before(list_head *new_entry, list_head *loca
/// @param entry the entry we want to remove.
static inline void list_head_remove(list_head *entry)
{
assert(entry && "Variable entry is NULL."); // Check for NULL entry
assert(entry->prev && "Attribute entry->prev is NULL."); // Check previous pointer
assert(entry->next && "Attribute entry->next is NULL."); // Check next pointer

// Check if the element is actually in a list.
if (!list_head_empty(entry)) {
assert(entry->prev && "Attribute entry->prev is NULL.");
assert(entry->next && "Attribute entry->next is NULL.");
// We link the `previous` element to the `next` one.
entry->prev->next = entry->next;
// We link the `next` element to the `previous` one.
Expand All @@ -151,6 +157,8 @@ static inline void list_head_remove(list_head *entry)
/// @return a list_head pointing to the element we removed, NULL on failure.
static inline list_head *list_head_pop(list_head *head)
{
assert(head && "Variable head is NULL."); // Check for NULL head

// Check if the list is not empty.
if (!list_head_empty(head)) {
// Store the pointer.
Expand All @@ -168,11 +176,14 @@ static inline list_head *list_head_pop(list_head *head)
/// @param secondary the secondary list, which gets appended, and re-initialized as empty.
static inline void list_head_append(list_head *main, list_head *secondary)
{
assert(main && "Variable main is NULL."); // Check for NULL main
assert(secondary && "Variable secondary is NULL."); // Check for NULL secondary

// Check that both lists are actually filled with entries.
if (!list_head_empty(main) && !list_head_empty(secondary)) {
assert(main->prev && "Attribute main->prev is NULL.");
assert(secondary->next && "Attribute secondary->next is NULL.");
assert(secondary->prev && "Attribute secondary->prev is NULL.");
assert(main->prev && "Attribute main->prev is NULL."); // Check main's previous pointer
assert(secondary->next && "Attribute secondary->next is NULL."); // Check secondary's next pointer
assert(secondary->prev && "Attribute secondary->prev is NULL."); // Check secondary's previous pointer
// Connect the last element of the main list to the first one of the secondary list.
main->prev->next = secondary->next;
// Connect the first element of the secondary list to the last one of the main list.
Expand All @@ -191,11 +202,15 @@ static inline void list_head_append(list_head *main, list_head *secondary)
/// @param entry2 the second entry which will take the place of the first entry.
static inline void list_head_replace(list_head *entry1, list_head *entry2)
{
assert(entry1 && "Variable entry1 is NULL."); // Check for NULL entry1
assert(entry2 && "Variable entry2 is NULL."); // Check for NULL entry2

// First we need to remove the second entry.
list_head_remove(entry2);
assert(entry2->next && "Attribute entry2->next is NULL.");
assert(entry2->prev && "Attribute entry2->prev is NULL.");
// Then, we can place second entry where the first entry is.
assert(entry2->next && "Attribute entry2->next is NULL."); // Check entry2's next pointer
assert(entry2->prev && "Attribute entry2->prev is NULL."); // Check entry2's previous pointer

// Then, we can place the second entry where the first entry is.
entry2->next = entry1->next;
entry2->next->prev = entry2;
entry2->prev = entry1->prev;
Expand All @@ -209,6 +224,9 @@ static inline void list_head_replace(list_head *entry1, list_head *entry2)
/// @param entry2 the second entry.
static inline void list_head_swap(list_head *entry1, list_head *entry2)
{
assert(entry1 && "Variable entry1 is NULL."); // Check for NULL entry1
assert(entry2 && "Variable entry2 is NULL."); // Check for NULL entry2

list_head *pos = entry2->prev;
list_head_replace(entry1, entry2);
if (pos == entry1) {
Expand Down
Loading

0 comments on commit 35e59ce

Please sign in to comment.