#include <stdio.h>
#include <stdlib.h>

struct list_t {
  struct list_t *next;
  void          *value;
};

struct list_t *list_new () {
  return (struct list_t *) malloc(sizeof(struct list_t));
}

void list_free (struct list_t *xs) {
  struct list_t *next = NULL;

  for (; xs != NULL; xs = next) {
    next = xs->next;
    free(xs);
  }
}

struct list_t *list_reverse (struct list_t *xs) {
  struct list_t *ret  = NULL;
  struct list_t *next = NULL;

  for (; xs != NULL; xs = xs->next) {
    if ((next = list_new()) == NULL) goto err;
    next->value = xs->value;
    next->next  = ret;
    ret = next;
  }
  goto ok;

err:
  list_free(ret);
ok:
  return ret;
}

struct list_t *list_int_prepend(int v, struct list_t *next) {
  struct list_t *this = list_new(); if (this == NULL) goto err1;
  void *val = malloc(sizeof(int));  if (val  == NULL) goto err2;
  this->next  = next;
  this->value = val;
  *((int*)val) = v;
  return this;
err2:
  list_free(this);
err1:
  return NULL;
}

void list_int_printf(struct list_t *this) {
  for (; this != NULL; this = this->next) {
    printf("%d ", *((int*)this->value));
  }
  printf("\n");
}

int main(void) {
  struct list_t *xs = NULL;
  xs = list_int_prepend(1, xs);
  xs = list_int_prepend(3, xs);
  xs = list_int_prepend(5, xs);
  xs = list_int_prepend(2, xs);
  xs = list_int_prepend(11, xs);
  struct list_t *ys = list_reverse(xs);
  list_int_printf(xs);
  list_int_printf(ys);
  list_free(xs);
  list_free(ys);
  return 0;
}