#include <yaml.h>
#include <stdio.h>

/*
 *  gcc -c yaml_error.c && gcc -lyaml -o yaml_error yaml_error.o
 */

int main(int _argc, char * _argv[])
{
  yaml_parser_t parser;
  yaml_event_t event;
  yaml_emitter_t emitter;

  yaml_parser_initialize(&parser);
  yaml_emitter_initialize(&emitter);

  unsigned char buf[1000];
  size_t written;
  yaml_emitter_set_output_string(&emitter, buf, 1000, &written);

  FILE * input = fopen(_argv[1], "rb");

  yaml_parser_set_input_file(&parser, input);

  int done = 0;

  do {
    if (!yaml_parser_parse(&parser, &event)) {
      goto error;
    }
    if (event.type == YAML_NO_EVENT) {
      printf("Event is YAML_NO_EVENT\n");
    } else if (event.type == YAML_STREAM_START_EVENT) {
      printf("Event is YAML_STREAM_START_EVENT\n");
    } else if (event.type == YAML_STREAM_END_EVENT) {
      printf("Event is YAML_STREAM_END_EVENT\n");
    } else if (event.type == YAML_DOCUMENT_START_EVENT) {
      printf("Event is YAML_DOCUMENT_START_EVENT\n");
    } else if (event.type == YAML_DOCUMENT_END_EVENT) {
      printf("Event is YAML_DOCUMENT_END_EVENT\n");
    } else if (event.type == YAML_ALIAS_EVENT) {
      printf("Event is YAML_ALIAS_EVENT\n");
    } else if (event.type == YAML_SCALAR_EVENT) {
      printf("Event is YAML_SCALAR_EVENT\n");
      if (! yaml_emitter_emit(&emitter, &event)) {
        goto emitter_error;
      }
      printf(">>%s<<\n", buf);
    } else if (event.type == YAML_SEQUENCE_START_EVENT) {
      printf("Event is YAML_SEQUENCE_START_EVENT\n");
    } else if (event.type == YAML_SEQUENCE_END_EVENT) {
      printf("Event is YAML_SEQUENCE_END_EVENT\n");
    } else if (event.type == YAML_MAPPING_START_EVENT) {
      printf("Event is YAML_MAPPING_START_EVENT\n");
    } else if (event.type == YAML_MAPPING_END_EVENT) {
      printf("Event is YAML_MAPPING_END_EVENT\n");
    } else {
      printf("Event is UNKNOWN\n");
    }
    done = (event.type == YAML_STREAM_END_EVENT);

  } while (!done);

  yaml_event_delete(&event);
  yaml_parser_delete(&parser);
  return 0;

  error:
    printf("Error!\n");
    return 1;

  emitter_error:
    fprintf(stderr, "Emitter error!\n");

    /* Display an emitter error message. */

    switch (emitter.error)
    {    
        case YAML_MEMORY_ERROR:
            fprintf(stderr, "Memory error: Not enough memory for emitting\n");
            break;

        case YAML_WRITER_ERROR:
            fprintf(stderr, "Writer error: %s\n", emitter.problem);
            break;

        case YAML_EMITTER_ERROR:
            fprintf(stderr, "Emitter error: %s\n", emitter.problem);
            break;

        default:
            /* Couldn't happen. */
            fprintf(stderr, "Internal error\n");
            break;
    }    
  return 2;
}
