Sparse linked list insert function 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-&gt;data = data;
    new_node-&gt;pos = pos;
    *list_handle = new_node;
    return 1;
  }
  /* If head pos == pos, replace and done*/
  if (current-&gt;pos == pos)
  {
    current-&gt;data = data;
    return 1;
  }
  else if (current-&gt;pos &gt; pos)
  {
    /* Create new node between current and next */
    ElementNode *new_node = make_node(pos, data);
    if (new_node == NULL)
    {
      return 0;
    }
    new_node-&gt;next = current;
    *list_handle = new_node;
    return 1;
  }
  /*Walk the list, until next hits the end*/
  while (current-&gt;next != NULL)
  {
    if (current-&gt;next-&gt;pos == pos)
    { /* If next pos equals post, replace, done*/
      current-&gt;next-&gt;data = data;
      return 1;
    }
    else if (current-&gt;next-&gt;pos &gt; pos)
    {
      /* Create new node between current and next */
      ElementNode *new_node = make_node(pos, data);
      if (new_node == NULL)
      {
        return 0;
      }
      ElementNode *next     = current-&gt;next;
      current-&gt;next         = new_node;
      new_node-&gt;next        = next;
      return 1;
    }
    /*walk the list*/
    current = current-&gt;next;
  }
  /* Append to the tail */
  ElementNode *new_node = make_node(pos, data);
  if (new_node == NULL)
  {
    return 0;
  }
  current-&gt;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) &amp;&amp; (result == -1))
  {
    if (current-&gt;pos == pos)
    {
      current-&gt;data = data;
      result = 0;
    }
    else if (current-&gt;pos &gt; pos)
    {
      ElementNode *new_node = make_node(pos, data);
      if (new_node == NULL)
      {
        result = 1;
      }
      if (previous == NULL)
      {
        *p_list_handle = new_node;
      }
      else
      {
        previous-&gt;next = new_node;
      }
      new_node-&gt;next = current;
      result = 0;
    }
    previous = current;
    current = current-&gt;next;
  }
  if (result == -1)
  {
    ElementNode *new_node = make_node(pos, data);
    if (new_node == NULL)
    {
      result = 0;
    }
    previous-&gt;next = new_node;
  }
  return result;
}
Do what you say


 * return 0 if operation is succesfull
 *        1 if malloc failed */



So if a malloc fails, you are supposed to return 1.  But when you do the actual check:  


    ElementNode *new_node = make_node(pos, data);
    /* Malloc fail check*/
    if (new_node == NULL)
    {
      return 0;
    }



You return 0.  

You return 1 on success -- the exact opposite of the comment.  You should either update the comment to match the code or change the code to match the comment.  Or remove the comment--if you have to read the code anyway, why bother?  

Keep it simple


      ElementNode *next     = current-&gt;next;
      current-&gt;next         = new_node;
      new_node-&gt;next        = next;



Why do you need next?  Consider 

      new_node-&gt;next = current-&gt;next;
      current-&gt;next = new_node;


You save an assignment and a variable declaration by just changing the order in which two lines happen.