I wrote this sparse linked list insert function, and there are nine return
statements. Is this a code smell? Is this badly implemented? I fear that it's hard to read, or hard to maintain.
/* NOT BUGS, TESTED AND WORKS CORRECTLY
* insert an element into a list
* list is ordered using pos
* if position pos is already occupied, the value of the node
* should be updated with val
* if val=0, then the element should be deleted
* return 0 if operation is succesfull
* 1 if malloc failed */
int insert_element(ElementNode_handle *list_handle, int pos, int data)
{
/*Record the head*/
ElementNode *current = *list_handle;
/* If data is 0, stop */
if (data == 0)
{
return 1;
}
/* If list is empty, crate new list*/
if (current == NULL)
{
/* Create new list */
ElementNode *new_node = make_node(pos, data);
/* Malloc fail check*/
if (new_node == NULL)
{
return 0;
}
new_node->data = data;
new_node->pos = pos;
*list_handle = new_node;
return 1;
}
/* If head pos == pos, replace and done*/
if (current->pos == pos)
{
current->data = data;
return 1;
}
else if (current->pos > pos)
{
/* Create new node between current and next */
ElementNode *new_node = make_node(pos, data);
if (new_node == NULL)
{
return 0;
}
new_node->next = current;
*list_handle = new_node;
return 1;
}
/*Walk the list, until next hits the end*/
while (current->next != NULL)
{
if (current->next->pos == pos)
{ /* If next pos equals post, replace, done*/
current->next->data = data;
return 1;
}
else if (current->next->pos > pos)
{
/* Create new node between current and next */
ElementNode *new_node = make_node(pos, data);
if (new_node == NULL)
{
return 0;
}
ElementNode *next = current->next;
current->next = new_node;
new_node->next = next;
return 1;
}
/*walk the list*/
current = current->next;
}
/* Append to the tail */
ElementNode *new_node = make_node(pos, data);
if (new_node == NULL)
{
return 0;
}
current->next = new_node;
return 1;
}
=== EDIT === Refactored based on @user1118321
/**
* @brief insert an element into a list
* @details
* list is ordered using pos if position
* pos is already occupied, the value of
* the node should be updated with data
* @param p_list_handle Opaque pointer to list
* @param pos Position to insert
* @param data data at position
* @return 0 = success, 1 = failed
*/
int insert_element(ElementNode_handle *p_list_handle, int pos, int data)
{
/*Record the head*/
ElementNode *current = *p_list_handle;
/*Record previous*/
ElementNode *previous = NULL;
/*End result*/
int result = -1;
if (data == 0)
{
delete_element(p_list_handle, pos);
return 0;
}
if (current == NULL)
{
return make_list(p_list_handle, pos, data);
}
while ((current != NULL) && (result == -1))
{
if (current->pos == pos)
{
current->data = data;
result = 0;
}
else if (current->pos > pos)
{
ElementNode *new_node = make_node(pos, data);
if (new_node == NULL)
{
result = 1;
}
if (previous == NULL)
{
*p_list_handle = new_node;
}
else
{
previous->next = new_node;
}
new_node->next = current;
result = 0;
}
previous = current;
current = current->next;
}
if (result == -1)
{
ElementNode *new_node = make_node(pos, data);
if (new_node == NULL)
{
result = 0;
}
previous->next = new_node;
}
return result;
}