Something 's not right. Still too complex. Ah. Lists are recursive. Their treatment should be recursive as well. Let's see…
void remove_if(node ** head, remove_fn rm)
{
node * entry = *head;
if (rm(entry))
{
*head = entry->next;
free(entry);
}
else
head = &entry->next;
remove_if(head, rm);
}
Ahh, much better: Now we can refactor: void remove_head(node ** head)
{
node * entry = *head;
*head = entry->next;
free(entry);
}
void remove_if(node ** head, remove_fn rm)
{
if (rm(*head))
remove_head(head)
else
head = &entry->next;
remove_if(head, rm);
}
I'm sure GCC will be able to optimize away the tail call.Edit: oops, I forgot to test for empty lists, which was implicit in the for loop I set out to remove…