/* liblouis Braille Translation and Back-Translation Library

   Copyright (C) 2015, 2016 Christian Egli, Swiss Library for the Blind, Visually Impaired
   and Print Disabled
   Copyright (C) 2017 Bert Frees

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <config.h>
#include <assert.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "internal.h"
#include "error.h"
#include "errno.h"
#include "progname.h"
#include "version-etc.h"
#include "brl_checks.h"

static const struct option longopts[] = {
	{ "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' },
	{ NULL, 0, NULL, 0 },
};

const char version_etc_copyright[] =
		"Copyright %s %d Swiss Library for the Blind, Visually Impaired and Print "
		"Disabled";

#define AUTHORS "Christian Egli"

static void
print_help(void) {
	printf("\
Usage: %s YAML_TEST_FILE\n",
			program_name);

	fputs("\
Run the tests defined in the YAML_TEST_FILE. Return 0 if all tests pass\n\
or 1 if any of the tests fail. The details of failing tests are printed\n\
to stderr.\n\n",
			stdout);

	fputs("\
  -h, --help          display this help and exit\n\
  -v, --version       display version information and exit\n",
			stdout);

	printf("\n");
	printf("Report bugs to %s.\n", PACKAGE_BUGREPORT);

#ifdef PACKAGE_PACKAGER_BUG_REPORTS
	printf("Report %s bugs to: %s\n", PACKAGE_PACKAGER, PACKAGE_PACKAGER_BUG_REPORTS);
#endif
#ifdef PACKAGE_URL
	printf("%s home page: <%s>\n", PACKAGE_NAME, PACKAGE_URL);
#endif
}

#define EXIT_SKIPPED 77

#ifdef HAVE_LIBYAML
#include <yaml.h>

const char *event_names[] = { "YAML_NO_EVENT", "YAML_STREAM_START_EVENT",
	"YAML_STREAM_END_EVENT", "YAML_DOCUMENT_START_EVENT", "YAML_DOCUMENT_END_EVENT",
	"YAML_ALIAS_EVENT", "YAML_SCALAR_EVENT", "YAML_SEQUENCE_START_EVENT",
	"YAML_SEQUENCE_END_EVENT", "YAML_MAPPING_START_EVENT", "YAML_MAPPING_END_EVENT" };
const char *encoding_names[] = { "YAML_ANY_ENCODING", "YAML_UTF8_ENCODING",
	"YAML_UTF16LE_ENCODING", "YAML_UTF16BE_ENCODING" };

const char *inline_table_prefix = "checkyaml_inline_";

yaml_parser_t parser;
yaml_event_t event;

char *file_name;

int errors = 0;
int count = 0;

static char const **emph_classes = NULL;

void
simple_error(const char *msg, yaml_parser_t *parser, yaml_event_t *event) {
	error_at_line(EXIT_FAILURE, 0, file_name,
			event->start_mark.line ? event->start_mark.line + 1
								   : parser->problem_mark.line + 1,
			"%s", msg);
}

void
yaml_parse_error(yaml_parser_t *parser) {
	error_at_line(EXIT_FAILURE, 0, file_name, parser->problem_mark.line + 1, "%s",
			parser->problem);
}

void
yaml_error(yaml_event_type_t expected, yaml_event_t *event) {
	error_at_line(EXIT_FAILURE, 0, file_name, event->start_mark.line + 1,
			"Expected %s (actual %s)", event_names[expected], event_names[event->type]);
}

char *
read_table(yaml_event_t *start_event, yaml_parser_t *parser) {
	char *table = NULL;
	if (start_event->type != YAML_SCALAR_EVENT ||
			strcmp((const char *)start_event->data.scalar.value, "table"))
		return 0;

	table = malloc(sizeof(char) * MAXSTRING);
	table[0] = '\0';
	yaml_event_t event;
	if (!yaml_parser_parse(parser, &event) ||
			!(event.type == YAML_SEQUENCE_START_EVENT || event.type == YAML_SCALAR_EVENT))
		error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
				"Expected %s or %s (actual %s)", event_names[YAML_SEQUENCE_START_EVENT],
				event_names[YAML_SCALAR_EVENT], event_names[event.type]);

	if (event.type == YAML_SEQUENCE_START_EVENT) {
		yaml_event_delete(&event);
		int done = 0;
		char *p = table;
		while (!done) {
			if (!yaml_parser_parse(parser, &event)) {
				yaml_parse_error(parser);
			}
			if (event.type == YAML_SEQUENCE_END_EVENT) {
				done = 1;
			} else if (event.type == YAML_SCALAR_EVENT) {
				if (table != p) strcat(p++, ",");
				strcat(p, (const char *)event.data.scalar.value);
				p += event.data.scalar.length;
			}
			yaml_event_delete(&event);
		}
		if (!lou_getTable(table))
			error_at_line(EXIT_FAILURE, 0, file_name, start_event->start_mark.line + 1,
					"Table %s not valid", table);
	} else {  // YAML_SCALAR_EVENT
		yaml_char_t *p = event.data.scalar.value;
		if (*p)
			while (p[1]) p++;
		if (*p == 10 || *p == 13) {
			// If the scalar ends with a newline, assume it is a block
			// scalar, so treat as an inline table. (Is there a proper way
			// to check for a block scalar?)
			sprintf(table, "%s%d", inline_table_prefix, rand());
			p = event.data.scalar.value;
			yaml_char_t *line_start = p;
			int line_len = 0;
			while (*p) {
				if (*p == 10 || *p == 13) {
					char *line = strndup((const char *)line_start, line_len);
					lou_compileString(table, line);
					free(line);
					line_start = p + 1;
					line_len = 0;
				} else {
					line_len++;
				}
				p++;
			}
		} else {
			strcat(table, (const char *)event.data.scalar.value);
		}
		yaml_event_delete(&event);
	}
	emph_classes = lou_getEmphClasses(table);  // get declared emphasis classes
	return table;
}

void
read_flags(yaml_parser_t *parser, int *direction, int *hyphenation) {
	yaml_event_t event;
	int parse_error = 1;

	*direction = 0;
	*hyphenation = 0;

	if (!yaml_parser_parse(parser, &event) || (event.type != YAML_MAPPING_START_EVENT))
		yaml_error(YAML_MAPPING_START_EVENT, &event);

	yaml_event_delete(&event);

	while ((parse_error = yaml_parser_parse(parser, &event)) &&
			(event.type == YAML_SCALAR_EVENT)) {
		if (!strcmp((const char *)event.data.scalar.value, "testmode")) {
			yaml_event_delete(&event);
			if (!yaml_parser_parse(parser, &event) || (event.type != YAML_SCALAR_EVENT))
				yaml_error(YAML_SCALAR_EVENT, &event);
			if (!strcmp((const char *)event.data.scalar.value, "forward")) {
				*direction = 0;
			} else if (!strcmp((const char *)event.data.scalar.value, "backward")) {
				*direction = 1;
			} else if (!strcmp((const char *)event.data.scalar.value, "hyphenate")) {
				*hyphenation = 1;
			} else {
				error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
						"Testmode '%s' not supported\n", event.data.scalar.value);
			}
		} else {
			error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
					"Flag '%s' not supported\n", event.data.scalar.value);
		}
	}
	if (!parse_error) yaml_parse_error(parser);
	if (event.type != YAML_MAPPING_END_EVENT) yaml_error(YAML_MAPPING_END_EVENT, &event);
	yaml_event_delete(&event);
}

int
read_xfail(yaml_parser_t *parser) {
	yaml_event_t event;
	/* assume xfail true if there is an xfail key */
	int xfail = 1;
	if (!yaml_parser_parse(parser, &event) || (event.type != YAML_SCALAR_EVENT))
		yaml_error(YAML_SCALAR_EVENT, &event);
	if (!strcmp((const char *)event.data.scalar.value, "false") ||
			!strcmp((const char *)event.data.scalar.value, "off"))
		xfail = 0;
	yaml_event_delete(&event);
	return xfail;
}

translationModes
read_mode(yaml_parser_t *parser) {
	yaml_event_t event;
	translationModes mode = 0;
	int parse_error = 1;

	if (!yaml_parser_parse(parser, &event) || (event.type != YAML_SEQUENCE_START_EVENT))
		yaml_error(YAML_SEQUENCE_START_EVENT, &event);
	yaml_event_delete(&event);

	while ((parse_error = yaml_parser_parse(parser, &event)) &&
			(event.type == YAML_SCALAR_EVENT)) {
		if (!strcmp((const char *)event.data.scalar.value, "noContractions")) {
			mode |= noContractions;
		} else if (!strcmp((const char *)event.data.scalar.value, "compbrlAtCursor")) {
			mode |= compbrlAtCursor;
		} else if (!strcmp((const char *)event.data.scalar.value, "dotsIO")) {
			mode |= dotsIO;
		} else if (!strcmp((const char *)event.data.scalar.value, "comp8Dots")) {
			mode |= comp8Dots;
		} else if (!strcmp((const char *)event.data.scalar.value, "pass1Only")) {
			mode |= pass1Only;
		} else if (!strcmp((const char *)event.data.scalar.value, "compbrlLeftCursor")) {
			mode |= compbrlLeftCursor;
		} else if (!strcmp((const char *)event.data.scalar.value, "ucBrl")) {
			mode |= ucBrl;
		} else if (!strcmp((const char *)event.data.scalar.value, "noUndefinedDots")) {
			mode |= noUndefinedDots;
		} else if (!strcmp((const char *)event.data.scalar.value, "partialTrans")) {
			mode |= partialTrans;
		} else {
			error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
					"Mode '%s' not supported\n", event.data.scalar.value);
		}
		yaml_event_delete(&event);
	}
	if (!parse_error) yaml_parse_error(parser);
	if (event.type != YAML_SEQUENCE_END_EVENT)
		yaml_error(YAML_SEQUENCE_END_EVENT, &event);
	yaml_event_delete(&event);
	return mode;
}

int *
read_inPos(yaml_parser_t *parser, int wrdlen, int translen) {
	int *pos = malloc(sizeof(int) * translen);
	int i = 0;
	yaml_event_t event;
	int parse_error = 1;
	char *tail;

	if (!yaml_parser_parse(parser, &event) || (event.type != YAML_SEQUENCE_START_EVENT))
		yaml_error(YAML_SEQUENCE_START_EVENT, &event);
	yaml_event_delete(&event);

	while ((parse_error = yaml_parser_parse(parser, &event)) &&
			(event.type == YAML_SCALAR_EVENT)) {
		if (i >= translen)
			error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
					"Too many input positions for translation of length %d.", translen);
		errno = 0;
		int val = strtol((const char *)event.data.scalar.value, &tail, 0);
		if (errno != 0)
			error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
					"Not a valid input position '%s'. Must be a number\n",
					event.data.scalar.value);
		if ((const char *)event.data.scalar.value == tail)
			error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
					"No digits found in input position '%s'. Must be a number\n",
					event.data.scalar.value);
		pos[i++] = val;
		yaml_event_delete(&event);
	}
	if (i < translen)
		error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
				"Too  few input positions (%i) for translation of length %i\n", i,
				translen);
	if (!parse_error) yaml_parse_error(parser);
	if (event.type != YAML_SEQUENCE_END_EVENT)
		yaml_error(YAML_SEQUENCE_END_EVENT, &event);
	yaml_event_delete(&event);
	return pos;
}

int *
read_outPos(yaml_parser_t *parser, int wrdlen, int translen) {
	int *pos = malloc(sizeof(int) * wrdlen);
	int i = 0;
	yaml_event_t event;
	int parse_error = 1;
	char *tail;

	if (!yaml_parser_parse(parser, &event) || (event.type != YAML_SEQUENCE_START_EVENT))
		yaml_error(YAML_SEQUENCE_START_EVENT, &event);
	yaml_event_delete(&event);

	while ((parse_error = yaml_parser_parse(parser, &event)) &&
			(event.type == YAML_SCALAR_EVENT)) {
		if (i >= wrdlen)
			error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
					"Too many output positions for input string of length %d.", translen);
		errno = 0;
		int val = strtol((const char *)event.data.scalar.value, &tail, 0);
		if (errno != 0)
			error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
					"Not a valid output position '%s'. Must be a number\n",
					event.data.scalar.value);
		if ((const char *)event.data.scalar.value == tail)
			error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
					"No digits found in output position '%s'. Must be a number\n",
					event.data.scalar.value);
		pos[i++] = val;
		yaml_event_delete(&event);
	}
	if (i < wrdlen)
		error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
				"Too few output positions (%i) for input string of length %i\n", i,
				wrdlen);
	if (!parse_error) yaml_parse_error(parser);
	if (event.type != YAML_SEQUENCE_END_EVENT)
		yaml_error(YAML_SEQUENCE_END_EVENT, &event);
	yaml_event_delete(&event);
	return pos;
}

int *
read_cursorPos(yaml_parser_t *parser, int wrdlen, int translen) {
	int *pos = malloc(sizeof(int) * wrdlen);
	int i = 0;
	yaml_event_t event;
	int parse_error = 1;
	char *tail;

	if (!yaml_parser_parse(parser, &event) || (event.type != YAML_SEQUENCE_START_EVENT))
		yaml_error(YAML_SEQUENCE_START_EVENT, &event);
	yaml_event_delete(&event);

	while ((parse_error = yaml_parser_parse(parser, &event)) &&
			(event.type == YAML_SCALAR_EVENT)) {
		if (i >= wrdlen)
			error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
					"Too many cursor positions for input string of length %d.", wrdlen);
		errno = 0;
		int val = strtol((const char *)event.data.scalar.value, &tail, 0);
		if (errno != 0)
			error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
					"Not a valid cursor position '%s'. Must be a number\n",
					event.data.scalar.value);
		if ((const char *)event.data.scalar.value == tail)
			error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
					"No digits found in cursor position '%s'. Must be a number\n",
					event.data.scalar.value);
		pos[i++] = val;
		yaml_event_delete(&event);
	}
	if (i < wrdlen)
		error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
				"Too few cursor positions (%i) for input string of length %i\n", i,
				wrdlen);
	if (!parse_error) yaml_parse_error(parser);
	if (event.type != YAML_SEQUENCE_END_EVENT)
		yaml_error(YAML_SEQUENCE_END_EVENT, &event);
	yaml_event_delete(&event);
	return pos;
}

void
read_typeform_string(yaml_parser_t *parser, formtype *typeform, typeforms kind, int len) {
	yaml_event_t event;
	int typeform_len;

	if (!yaml_parser_parse(parser, &event) || (event.type != YAML_SCALAR_EVENT))
		yaml_error(YAML_SCALAR_EVENT, &event);
	typeform_len = strlen((const char *)event.data.scalar.value);
	if (typeform_len != len)
		error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
				"Too many or too typeforms (%i) for word of length %i\n", typeform_len,
				len);
	update_typeform((const char *)event.data.scalar.value, typeform, kind);
	yaml_event_delete(&event);
}

formtype *
read_typeforms(yaml_parser_t *parser, int len) {
	yaml_event_t event;
	formtype *typeform = calloc(len, sizeof(formtype));
	int parse_error = 1;

	if (!yaml_parser_parse(parser, &event) || (event.type != YAML_MAPPING_START_EVENT))
		yaml_error(YAML_MAPPING_START_EVENT, &event);
	yaml_event_delete(&event);

	while ((parse_error = yaml_parser_parse(parser, &event)) &&
			(event.type == YAML_SCALAR_EVENT)) {
		if (strcmp((const char *)event.data.scalar.value, "computer_braille") == 0) {
			yaml_event_delete(&event);
			read_typeform_string(parser, typeform, computer_braille, len);
		} else if (strcmp((const char *)event.data.scalar.value, "no_translate") == 0) {
			yaml_event_delete(&event);
			read_typeform_string(parser, typeform, no_translate, len);
		} else if (strcmp((const char *)event.data.scalar.value, "no_contract") == 0) {
			yaml_event_delete(&event);
			read_typeform_string(parser, typeform, no_contract, len);
		} else {
			int i;
			typeforms kind = plain_text;
			for (i = 0; emph_classes[i]; i++) {
				if (strcmp((const char *)event.data.scalar.value, emph_classes[i]) == 0) {
					yaml_event_delete(&event);
					kind = italic << i;
					if (kind > emph_10)
						error_at_line(EXIT_FAILURE, 0, file_name,
								event.start_mark.line + 1,
								"Typeform '%s' was not declared\n",
								event.data.scalar.value);
					read_typeform_string(parser, typeform, kind, len);
					break;
				}
			}
		}
	}
	if (!parse_error) yaml_parse_error(parser);

	if (event.type != YAML_MAPPING_END_EVENT) yaml_error(YAML_MAPPING_END_EVENT, &event);
	yaml_event_delete(&event);
	return typeform;
}

void
read_options(yaml_parser_t *parser, int wordLen, int translationLen, int *xfail,
		translationModes *mode, formtype **typeform, int **inPos, int **outPos,
		int **cursorPos) {
	yaml_event_t event;
	char *option_name;
	int parse_error = 1;

	*mode = 0;
	*xfail = 0;
	*typeform = NULL;
	*inPos = NULL;
	*outPos = NULL;
	*cursorPos = NULL;

	while ((parse_error = yaml_parser_parse(parser, &event)) &&
			(event.type == YAML_SCALAR_EVENT)) {
		option_name =
				strndup((const char *)event.data.scalar.value, event.data.scalar.length);

		if (!strcmp(option_name, "xfail")) {
			yaml_event_delete(&event);
			*xfail = read_xfail(parser);
		} else if (!strcmp(option_name, "mode")) {
			yaml_event_delete(&event);
			*mode = read_mode(parser);
		} else if (!strcmp(option_name, "typeform")) {
			yaml_event_delete(&event);
			*typeform = read_typeforms(parser, wordLen);
		} else if (!strcmp(option_name, "inputPos")) {
			yaml_event_delete(&event);
			*inPos = read_inPos(parser, wordLen, translationLen);
		} else if (!strcmp(option_name, "outputPos")) {
			yaml_event_delete(&event);
			*outPos = read_outPos(parser, wordLen, translationLen);
		} else if (!strcmp(option_name, "cursorPos")) {
			yaml_event_delete(&event);
			*cursorPos = read_cursorPos(parser, wordLen, translationLen);
		} else {
			error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
					"Unsupported option %s", option_name);
		}
		free(option_name);
	}
	if (!parse_error) yaml_parse_error(parser);
	if (event.type != YAML_MAPPING_END_EVENT) yaml_error(YAML_MAPPING_END_EVENT, &event);
	yaml_event_delete(&event);
}

/* see http://stackoverflow.com/questions/5117393/utf-8-strings-length-in-linux-c */
int
my_strlen_utf8_c(char *s) {
	int i = 0, j = 0;
	while (s[i]) {
		if ((s[i] & 0xc0) != 0x80) j++;
		i++;
	}
	return j;
}

void
read_test(yaml_parser_t *parser, char **tables, int direction, int hyphenation) {
	yaml_event_t event;
	char *description = NULL;
	char *word;
	char *translation;
	int xfail = 0;
	translationModes mode = 0;
	formtype *typeform = NULL;
	int *inPos = NULL;
	int *outPos = NULL;
	int *cursorPos = NULL;

	if (!yaml_parser_parse(parser, &event) || (event.type != YAML_SCALAR_EVENT))
		simple_error("Word expected", parser, &event);

	word = strndup((const char *)event.data.scalar.value, event.data.scalar.length);
	yaml_event_delete(&event);

	if (!yaml_parser_parse(parser, &event) || (event.type != YAML_SCALAR_EVENT))
		simple_error("Translation expected", parser, &event);

	translation =
			strndup((const char *)event.data.scalar.value, event.data.scalar.length);
	yaml_event_delete(&event);

	if (!yaml_parser_parse(parser, &event)) yaml_parse_error(parser);

	/* Handle an optional description */
	if (event.type == YAML_SCALAR_EVENT) {
		description = word;
		word = translation;
		translation =
				strndup((const char *)event.data.scalar.value, event.data.scalar.length);
		yaml_event_delete(&event);

		if (!yaml_parser_parse(parser, &event)) yaml_parse_error(parser);
	}

	if (event.type == YAML_MAPPING_START_EVENT) {
		yaml_event_delete(&event);
		read_options(parser, my_strlen_utf8_c(word), my_strlen_utf8_c(translation),
				&xfail, &mode, &typeform, &inPos, &outPos, &cursorPos);

		if (!yaml_parser_parse(parser, &event) || (event.type != YAML_SEQUENCE_END_EVENT))
			yaml_error(YAML_SEQUENCE_END_EVENT, &event);
	} else if (event.type != YAML_SEQUENCE_END_EVENT) {
		error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
				"Expected %s or %s (actual %s)", event_names[YAML_MAPPING_START_EVENT],
				event_names[YAML_SEQUENCE_END_EVENT], event_names[event.type]);
	}

	int result = 0;
	char **table = tables;
	while (*table) {
		if (inPos || outPos || cursorPos) {
			result |= check_full(
					*table, word, typeform, translation, mode, NULL, direction, !xfail);
			if (inPos) result |= check_inpos(*table, word, inPos);
			if (outPos) result |= check_outpos(*table, word, outPos);
			if (cursorPos) result |= check_cursor_pos(*table, word, cursorPos);
		} else if (hyphenation) {
			result |= check_hyphenation(*table, word, translation);
		} else {
			// FIXME: Note that the typeform array was constructed using the
			// emphasis classes mapping of the last compiled table. This
			// means that if we are testing multiple tables at the same time
			// they must have the same mapping (i.e. the emphasis classes
			// must be defined in the same order).
			result |= check_full(
					*table, word, typeform, translation, mode, NULL, direction, !xfail);
		}
		table++;
	}
	if (xfail != result) {
		if (description) fprintf(stderr, "%s\n", description);
		error_at_line(0, 0, file_name, event.start_mark.line + 1,
				(xfail ? "Unexpected Pass" : "Failure"));
		errors++;
	}
	yaml_event_delete(&event);
	count++;

	free(description);
	free(word);
	free(translation);
	free(typeform);
	free(inPos);
	free(outPos);
	free(cursorPos);
}

void
read_tests(yaml_parser_t *parser, char **tables, int direction, int hyphenation) {
	yaml_event_t event;
	if (!yaml_parser_parse(parser, &event) || (event.type != YAML_SEQUENCE_START_EVENT))
		yaml_error(YAML_SEQUENCE_START_EVENT, &event);

	yaml_event_delete(&event);

	int done = 0;
	while (!done) {
		if (!yaml_parser_parse(parser, &event)) {
			yaml_parse_error(parser);
		}
		if (event.type == YAML_SEQUENCE_END_EVENT) {
			done = 1;
			yaml_event_delete(&event);
		} else if (event.type == YAML_SEQUENCE_START_EVENT) {
			yaml_event_delete(&event);
			read_test(parser, tables, direction, hyphenation);
		} else {
			error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
					"Expected %s or %s (actual %s)", event_names[YAML_SEQUENCE_END_EVENT],
					event_names[YAML_SEQUENCE_START_EVENT], event_names[event.type]);
		}
	}
}

/*
 * This custom table resolver handles magic table names that represent
 * inline tables.
 */
static char **
customTableResolver(const char *tableList, const char *base) {
	static char *dummy_table[1];
	if (strncmp(tableList, inline_table_prefix, strlen(inline_table_prefix)) == 0)
		return dummy_table;
	return _lou_defaultTableResolver(tableList, base);
}

#endif  // HAVE_LIBYAML

int
main(int argc, char *argv[]) {
	int optc;

	set_program_name(argv[0]);

	while ((optc = getopt_long(argc, argv, "hv", longopts, NULL)) != -1) switch (optc) {
		/* --help and --version exit immediately, per GNU coding standards.  */
		case 'v':
			version_etc(
					stdout, program_name, PACKAGE_NAME, VERSION, AUTHORS, (char *)NULL);
			exit(EXIT_SUCCESS);
			break;
		case 'h':
			print_help();
			exit(EXIT_SUCCESS);
			break;
		default:
			fprintf(stderr, "Try `%s --help' for more information.\n", program_name);
			exit(EXIT_FAILURE);
			break;
		}

	if (optind != argc - 1) {
		/* Print error message and exit.  */
		if (optind < argc - 1)
			fprintf(stderr, "%s: extra operand: %s\n", program_name, argv[optind + 1]);
		else
			fprintf(stderr, "%s: no YAML test file specified\n", program_name);

		fprintf(stderr, "Try `%s --help' for more information.\n", program_name);
		exit(EXIT_FAILURE);
	}

#ifdef WITHOUT_YAML
	fprintf(stderr,
			"Skipping tests for %s as yaml was disabled in configure with "
			"--without-yaml\n",
			argv[1]);
	return EXIT_SKIPPED;
#else
#ifndef HAVE_LIBYAML
	fprintf(stderr, "Skipping tests for %s as libyaml was not found\n", argv[1]);
	return EXIT_SKIPPED;
#endif  // not HAVE_LIBYAML
#endif  // WITHOUT_YAML

#ifndef WITHOUT_YAML
#ifdef HAVE_LIBYAML

	FILE *file;
	yaml_parser_t parser;
	yaml_event_t event;

	file_name = argv[1];
	file = fopen(file_name, "rb");
	if (!file) {
		fprintf(stderr, "%s: file not found: %s\n", program_name, file_name);
		exit(3);
	}

	char *dir_name = strdup(file_name);
	int i = strlen(dir_name);
	while (i > 0) {
		if (dir_name[i - 1] == '/' || dir_name[i - 1] == '\\') {
			i--;
			break;
		}
		i--;
	}
	dir_name[i] = '\0';
	// FIXME: problem with this is that
	// LOUIS_TABLEPATH=$(top_srcdir)/tables,... does not work anymore because
	// $(top_srcdir) == .. (not an absolute path)
	chdir(dir_name);

	// register custom table resolver
	lou_registerTableResolver(&customTableResolver);

	assert(yaml_parser_initialize(&parser));

	yaml_parser_set_input_file(&parser, file);

	if (!yaml_parser_parse(&parser, &event) || (event.type != YAML_STREAM_START_EVENT)) {
		yaml_error(YAML_STREAM_START_EVENT, &event);
	}

	if (event.data.stream_start.encoding != YAML_UTF8_ENCODING)
		error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
				"UTF-8 encoding expected (actual %s)",
				encoding_names[event.data.stream_start.encoding]);
	yaml_event_delete(&event);

	if (!yaml_parser_parse(&parser, &event) ||
			(event.type != YAML_DOCUMENT_START_EVENT)) {
		yaml_error(YAML_DOCUMENT_START_EVENT, &event);
	}
	yaml_event_delete(&event);

	if (!yaml_parser_parse(&parser, &event) || (event.type != YAML_MAPPING_START_EVENT)) {
		yaml_error(YAML_MAPPING_START_EVENT, &event);
	}
	yaml_event_delete(&event);

	if (!yaml_parser_parse(&parser, &event))
		simple_error("table expected", &parser, &event);

	int MAXTABLES = 10;
	char *tables[MAXTABLES + 1];
	while ((tables[0] = read_table(&event, &parser))) {
		yaml_event_delete(&event);
		int k = 1;
		while (1) {
			if (!yaml_parser_parse(&parser, &event))
				error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
						"Expected table or %s (actual %s)",
						event_names[YAML_SCALAR_EVENT], event_names[event.type]);
			if ((tables[k++] = read_table(&event, &parser))) {
				if (k == MAXTABLES) exit(EXIT_FAILURE);
				yaml_event_delete(&event);
			} else
				break;
		}

		if (event.type != YAML_SCALAR_EVENT) yaml_error(YAML_SCALAR_EVENT, &event);

		int direction = 0;
		int hyphenation = 0;
		if (!strcmp((const char *)event.data.scalar.value, "flags")) {
			yaml_event_delete(&event);
			read_flags(&parser, &direction, &hyphenation);

			if (!yaml_parser_parse(&parser, &event) ||
					(event.type != YAML_SCALAR_EVENT) ||
					strcmp((const char *)event.data.scalar.value, "tests")) {
				simple_error("tests expected", &parser, &event);
			}
			yaml_event_delete(&event);
			read_tests(&parser, tables, direction, hyphenation);

		} else if (!strcmp((const char *)event.data.scalar.value, "tests")) {
			yaml_event_delete(&event);
			read_tests(&parser, tables, direction, hyphenation);
		} else {
			simple_error("flags or tests expected", &parser, &event);
		}

		char **p = tables;
		while (*p) free(*(p++));

		if (!yaml_parser_parse(&parser, &event))
			error_at_line(EXIT_FAILURE, 0, file_name, event.start_mark.line + 1,
					"Expected table or %s (actual %s)",
					event_names[YAML_MAPPING_END_EVENT], event_names[event.type]);
	}
	if (event.type != YAML_MAPPING_END_EVENT) yaml_error(YAML_MAPPING_END_EVENT, &event);
	yaml_event_delete(&event);

	if (!yaml_parser_parse(&parser, &event) || (event.type != YAML_DOCUMENT_END_EVENT)) {
		yaml_error(YAML_DOCUMENT_END_EVENT, &event);
	}
	yaml_event_delete(&event);

	if (!yaml_parser_parse(&parser, &event) || (event.type != YAML_STREAM_END_EVENT)) {
		yaml_error(YAML_STREAM_END_EVENT, &event);
	}
	yaml_event_delete(&event);

	yaml_parser_delete(&parser);

	free(emph_classes);
	lou_free();

	assert(!fclose(file));

	printf("%s (%d tests, %d failure%s)\n", (errors ? "FAILURE" : "SUCCESS"), count,
			errors, ((errors != 1) ? "s" : ""));

	return errors ? 1 : 0;

#endif  // HAVE_LIBYAML
#endif  // not WITHOUT_YAML
}
