La función pondrá el nodo generado con el dato al final de la lista. Siguiendo la primera premisa éste último nodo debe apuntar a NULL en next.
Lo que se hace es:
Se genera un nodo a partir de la información dada por data.
Si la lista está vacía, NULL, pasará a apuntar al nodo nuevo.
Si la lista no está vacía hay que recorrerla hasta encontrar el último elemento (aquel que apunte a NULL), cambiar el valor next para que apunte al nuevo nodo generado y regresar la lista entera, eso es el primer elemento (list).
Lo que ves en
Código
es precisamente ese recorrido. node apunta al principio de la lista (list) y vamos a trabajar sobre node. Mientras el elemento next de node no sea NULL, node apuntará a node->next (en el código esto está encapsulado por node = slist_next(node). Una vez llegado a éste último elemento la orden list_next(node) = newNode; coloca el nuevo nodo al final de la lista.
while (slist_next(node) != slist_nil()) { node = slist_next(node);
Como el inicio de la lista no ha sido modificado (list) y hay que regresar un puntero, precisamente al inicio de la lista, devolvemos list.
Otra versión sin estas macros es así:
Código
SList slist_append(SList list, int data) { Slist node; newNode->data = data; newNode->next = NULL; if(list == NULL) return newNode; node = list; while(node->next != NULL) node = node->next; node->next = newNode; return list; }