1284345Ssjg/*
2284345Ssjg * Copyright 2017      Sven Verdoolaege
3284345Ssjg *
4284345Ssjg * Use of this software is governed by the MIT license
5284345Ssjg *
6284481Ssjg * Written by Sven Verdoolaege.
7284345Ssjg */
8284345Ssjg
9284345Ssjg#include <stdlib.h>
10284345Ssjg
11284345Ssjg#include <isl/arg.h>
12284345Ssjg#include <isl/options.h>
13284345Ssjg#include <isl/union_map.h>
14284345Ssjg#include <isl/stream.h>
15284345Ssjg
16284345Ssjgstruct options {
17284345Ssjg	struct isl_options *isl;
18284345Ssjg	char *flow1;
19284345Ssjg	char *flow2;
20284345Ssjg};
21284345Ssjg
22284345SsjgISL_ARGS_START(struct options, options_args)
23284345SsjgISL_ARG_CHILD(struct options, isl, "isl", &isl_options_args, "isl options")
24ISL_ARG_ARG(struct options, flow1, "flow1", NULL)
25ISL_ARG_ARG(struct options, flow2, "flow2", NULL)
26ISL_ARGS_END
27
28ISL_ARG_DEF(options, struct options, options_args)
29
30static void die(const char *msg)
31{
32	fprintf(stderr, "%s\n", msg);
33	exit(EXIT_FAILURE);
34}
35
36static FILE *open_or_die(const char *filename)
37{
38	FILE *file;
39
40	file = fopen(filename, "r");
41	if (!file) {
42		fprintf(stderr, "Unable to open %s\n", filename);
43		exit(EXIT_FAILURE);
44	}
45	return file;
46}
47
48#undef BASE
49#define BASE union_map
50#include "read_in_string_templ.c"
51
52/* Given two YAML descriptions of isl_union_flow objects, check whether
53 * they are equivalent.
54 * Return EXIT_SUCCESS if they are and EXIT_FAILURE if they are not
55 * or if anything else went wrong.
56 *
57 * The descriptions are checked field by field, meaning that the fields
58 * are expected to appear in the same order in both inputs.
59 */
60int main(int argc, char **argv)
61{
62	isl_bool more;
63	isl_ctx *ctx;
64	struct options *options;
65	FILE *input1, *input2;
66	isl_stream *s1, *s2;
67
68	options = options_new_with_defaults();
69	if (!options)
70		return EXIT_FAILURE;
71
72	ctx = isl_ctx_alloc_with_options(&options_args, options);
73	argc = options_parse(options, argc, argv, ISL_ARG_ALL);
74
75	input1 = open_or_die(options->flow1);
76	input2 = open_or_die(options->flow2);
77	s1 = isl_stream_new_file(ctx, input1);
78	s2 = isl_stream_new_file(ctx, input2);
79
80	if (isl_stream_yaml_read_start_mapping(s1) < 0)
81		isl_die(ctx, isl_error_unknown, "arg1 not a YAML mapping",
82			return EXIT_FAILURE);
83	if (isl_stream_yaml_read_start_mapping(s2) < 0)
84		isl_die(ctx, isl_error_unknown, "arg2 not a YAML mapping",
85			return EXIT_FAILURE);
86
87	while ((more = isl_stream_yaml_next(s1)) == isl_bool_true) {
88		isl_bool more2;
89		isl_bool equal;
90		isl_union_map *umap1, *umap2;
91
92		more2 = isl_stream_yaml_next(s2);
93		if (more2 < 0)
94			return EXIT_FAILURE;
95		if (!more2)
96			isl_die(ctx, isl_error_unknown, "arg2 shorter",
97				return EXIT_FAILURE);
98		if (isl_stream_eat(s1, ISL_TOKEN_IDENT) < 0)
99			return EXIT_FAILURE;
100		if (isl_stream_eat(s2, ISL_TOKEN_IDENT) < 0)
101			return EXIT_FAILURE;
102		more = isl_stream_yaml_next(s1);
103		more2 = isl_stream_yaml_next(s2);
104		if (more < 0 || more2 < 0)
105			return EXIT_FAILURE;
106		if (!more || !more2)
107			isl_die(ctx, isl_error_unknown, "missing value",
108				return EXIT_FAILURE);
109
110		umap1 = read_union_map(s1);
111		umap2 = read_union_map(s2);
112		equal = isl_union_map_is_equal(umap1, umap2);
113		isl_union_map_free(umap1);
114		isl_union_map_free(umap2);
115		if (equal < 0)
116			return EXIT_FAILURE;
117		if (!equal)
118			die("field not equal");
119	}
120	if (more < 0)
121		return EXIT_FAILURE;
122
123
124	if (isl_stream_yaml_read_end_mapping(s1) < 0)
125		return EXIT_FAILURE;
126	if (isl_stream_yaml_read_end_mapping(s2) < 0)
127		return EXIT_FAILURE;
128
129	isl_stream_free(s1);
130	isl_stream_free(s2);
131	fclose(input1);
132	fclose(input2);
133	isl_ctx_free(ctx);
134
135	return EXIT_SUCCESS;
136}
137