int s_list_remove_if()

in common/src/s_list.c [230:284]


int s_list_remove_if(PS_LIST_ENTRY list_head, S_LIST_CONDITION_FUNCTION condition_function, const void* match_context)
{
    int result;
    if (
    /* Codes_SRS_S_LIST_07_026: [ If list_head is NULL, s_list_remove_if shall fail and return a non-zero value. ]*/
    (list_head == NULL) ||
    /* Codes_SRS_S_LIST_07_027: [ If condition_function is NULL, s_list_remove_if shall fail and return a non-zero value. ]*/
        (condition_function == NULL))
    {
        LogError("Invalid arguments (list_head=%p, condition_function=%p)", list_head, condition_function);
        result = MU_FAILURE;
    }
    else
    {
        PS_LIST_ENTRY prev_item = list_head;
        PS_LIST_ENTRY current_item = list_head->next;

        if (current_item == NULL)
        {
            /* Codes_SRS_S_LIST_07_040: [ If the list is empty, s_list_find shall return a non-zero value. ]*/
            result = MU_FAILURE;
        }
        else
        {
            /* Codes_SRS_S_LIST_07_028: [ s_list_remove_if shall iterate through all entris in a list, remove all that satisfies the condition_function and return zero. ]*/
            while (current_item != NULL)
            {
                bool continue_processing = false;

                /* Codes_SRS_S_LIST_07_029: [ s_list_remove_if shall determine whether an entry satisfies the condition criteria by invoking the condition function for that entry. ]*/
                if (condition_function(current_item, match_context, &continue_processing) == true)
                {
                    /* Codes_SRS_S_LIST_07_030: [ If the condition_function returns true, s_list_remove_if shall consider that entry as to be removed. ]*/
                    prev_item->next = current_item->next;
                }
                else
                {
                    /* Codes_SRS_S_LIST_07_031: [ If the condition_function returns false, s_list_remove_if shall consider that entry as not to be removed. ]*/
                    prev_item = current_item;
                }

                /* Codes_SRS_S_LIST_07_032: [ If the condition_function returns continue_processing as false, s_list_remove_if shall stop iterating through the list and return. ]*/
                if (continue_processing == false)
                {
                    break;
                }

                current_item = current_item->next;
            }
            result = 0;
        }
    }

    return result;
}