xref: /freebsd/tools/regression/geom/ConfCmp/ConfCmp.c (revision a99aa4c4834e5f48a12096eb21593eb8bbba22ea)
131304807SPoul-Henning Kamp /*-
231304807SPoul-Henning Kamp  * Copyright (c) 2002 Poul-Henning Kamp
331304807SPoul-Henning Kamp  * Copyright (c) 2002 Networks Associates Technology, Inc.
431304807SPoul-Henning Kamp  * All rights reserved.
531304807SPoul-Henning Kamp  *
631304807SPoul-Henning Kamp  * This software was developed for the FreeBSD Project by Poul-Henning Kamp
731304807SPoul-Henning Kamp  * and NAI Labs, the Security Research Division of Network Associates, Inc.
831304807SPoul-Henning Kamp  * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
931304807SPoul-Henning Kamp  * DARPA CHATS research program.
1031304807SPoul-Henning Kamp  *
1131304807SPoul-Henning Kamp  * Redistribution and use in source and binary forms, with or without
1231304807SPoul-Henning Kamp  * modification, are permitted provided that the following conditions
1331304807SPoul-Henning Kamp  * are met:
1431304807SPoul-Henning Kamp  * 1. Redistributions of source code must retain the above copyright
1531304807SPoul-Henning Kamp  *    notice, this list of conditions and the following disclaimer.
1631304807SPoul-Henning Kamp  * 2. Redistributions in binary form must reproduce the above copyright
1731304807SPoul-Henning Kamp  *    notice, this list of conditions and the following disclaimer in the
1831304807SPoul-Henning Kamp  *    documentation and/or other materials provided with the distribution.
1931304807SPoul-Henning Kamp  * 3. The names of the authors may not be used to endorse or promote
2031304807SPoul-Henning Kamp  *    products derived from this software without specific prior written
2131304807SPoul-Henning Kamp  *    permission.
2231304807SPoul-Henning Kamp  *
2331304807SPoul-Henning Kamp  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2431304807SPoul-Henning Kamp  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2531304807SPoul-Henning Kamp  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2631304807SPoul-Henning Kamp  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2731304807SPoul-Henning Kamp  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2831304807SPoul-Henning Kamp  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2931304807SPoul-Henning Kamp  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3031304807SPoul-Henning Kamp  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3131304807SPoul-Henning Kamp  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3231304807SPoul-Henning Kamp  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3331304807SPoul-Henning Kamp  * SUCH DAMAGE.
3431304807SPoul-Henning Kamp  *
3531304807SPoul-Henning Kamp  * $FreeBSD$
3631304807SPoul-Henning Kamp  */
3731304807SPoul-Henning Kamp 
3831304807SPoul-Henning Kamp #include <stdio.h>
3931304807SPoul-Henning Kamp #include <stdlib.h>
4031304807SPoul-Henning Kamp #include <string.h>
4131304807SPoul-Henning Kamp #include <unistd.h>
4231304807SPoul-Henning Kamp #include <fcntl.h>
4331304807SPoul-Henning Kamp #include <ctype.h>
4431304807SPoul-Henning Kamp #include <sys/stat.h>
4531304807SPoul-Henning Kamp #include <sys/mman.h>
4631304807SPoul-Henning Kamp #include <sys/queue.h>
4731304807SPoul-Henning Kamp #include <sys/sbuf.h>
4831304807SPoul-Henning Kamp #include <err.h>
495624b2d4SPoul-Henning Kamp #include <bsdxml.h>
5031304807SPoul-Henning Kamp 
51a99aa4c4SPoul-Henning Kamp FILE *fsubs;
52a99aa4c4SPoul-Henning Kamp 
5331304807SPoul-Henning Kamp struct node {
5431304807SPoul-Henning Kamp 	LIST_HEAD(, node)	children;
5531304807SPoul-Henning Kamp 	LIST_ENTRY(node)	siblings;
5631304807SPoul-Henning Kamp 	struct node		*parent;
5700d1e0f6SPoul-Henning Kamp 	const char		*name;
5831304807SPoul-Henning Kamp 	struct sbuf		*cont;
5931304807SPoul-Henning Kamp 	struct sbuf		*key;
6000d1e0f6SPoul-Henning Kamp 	char			*id;
6100d1e0f6SPoul-Henning Kamp 	char			*ref;
6231304807SPoul-Henning Kamp };
6331304807SPoul-Henning Kamp 
6431304807SPoul-Henning Kamp struct mytree {
6531304807SPoul-Henning Kamp 	struct node		*top;
6631304807SPoul-Henning Kamp 	struct node		*cur;
6731304807SPoul-Henning Kamp 	int			indent;
686de2a2e8SPoul-Henning Kamp 	int			ignore;
6931304807SPoul-Henning Kamp };
7031304807SPoul-Henning Kamp 
7131304807SPoul-Henning Kamp struct ref {
7231304807SPoul-Henning Kamp 	LIST_ENTRY(ref)		next;
7331304807SPoul-Henning Kamp 	char 			*k1;
7431304807SPoul-Henning Kamp 	char			*k2;
7531304807SPoul-Henning Kamp };
7631304807SPoul-Henning Kamp 
7731304807SPoul-Henning Kamp LIST_HEAD(, ref)		refs = LIST_HEAD_INITIALIZER(&refs);
7831304807SPoul-Henning Kamp 
7931304807SPoul-Henning Kamp static struct node *
8031304807SPoul-Henning Kamp new_node(void)
8131304807SPoul-Henning Kamp {
8231304807SPoul-Henning Kamp 	struct node *np;
8331304807SPoul-Henning Kamp 
8431304807SPoul-Henning Kamp 	np = calloc(1, sizeof *np);
8531304807SPoul-Henning Kamp 	np->cont = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
8631304807SPoul-Henning Kamp 	sbuf_clear(np->cont);
8731304807SPoul-Henning Kamp 	np->key = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
8831304807SPoul-Henning Kamp 	sbuf_clear(np->key);
8931304807SPoul-Henning Kamp 	LIST_INIT(&np->children);
9031304807SPoul-Henning Kamp 	return (np);
9131304807SPoul-Henning Kamp }
9231304807SPoul-Henning Kamp 
9331304807SPoul-Henning Kamp static void
9431304807SPoul-Henning Kamp indent(int n)
9531304807SPoul-Henning Kamp {
9631304807SPoul-Henning Kamp 
9731304807SPoul-Henning Kamp 	printf("%*.*s", n, n, "");
9831304807SPoul-Henning Kamp }
9931304807SPoul-Henning Kamp 
10031304807SPoul-Henning Kamp static void
10100d1e0f6SPoul-Henning Kamp StartElement(void *userData, const char *name, const char **attr)
10231304807SPoul-Henning Kamp {
10331304807SPoul-Henning Kamp 	struct mytree *mt;
10431304807SPoul-Henning Kamp 	struct node *np;
10500d1e0f6SPoul-Henning Kamp 	int i;
10631304807SPoul-Henning Kamp 
10731304807SPoul-Henning Kamp 	mt = userData;
1086de2a2e8SPoul-Henning Kamp 	if (!strcmp(name, "FreeBSD")) {
1096de2a2e8SPoul-Henning Kamp 		mt->ignore = 1;
1106de2a2e8SPoul-Henning Kamp 		return;
1116de2a2e8SPoul-Henning Kamp 	}
1126de2a2e8SPoul-Henning Kamp 	mt->ignore = 0;
11331304807SPoul-Henning Kamp 	mt->indent += 2;
11431304807SPoul-Henning Kamp 	np = new_node();
11500d1e0f6SPoul-Henning Kamp 	for (i = 0; attr[i]; i += 2) {
11600d1e0f6SPoul-Henning Kamp 		if (!strcmp(attr[i], "id"))
11700d1e0f6SPoul-Henning Kamp 			np->id = strdup(attr[i+1]);
11800d1e0f6SPoul-Henning Kamp 		else if (!strcmp(attr[i], "ref"))
11900d1e0f6SPoul-Henning Kamp 			np->ref = strdup(attr[i+1]);
12000d1e0f6SPoul-Henning Kamp 	}
12131304807SPoul-Henning Kamp 	np->name = strdup(name);
12231304807SPoul-Henning Kamp 	sbuf_cat(np->key, name);
12331304807SPoul-Henning Kamp 	sbuf_cat(np->key, "::");
12431304807SPoul-Henning Kamp 	np->parent = mt->cur;
12531304807SPoul-Henning Kamp 	LIST_INSERT_HEAD(&mt->cur->children, np, siblings);
12631304807SPoul-Henning Kamp 	mt->cur = np;
12731304807SPoul-Henning Kamp }
12831304807SPoul-Henning Kamp 
12931304807SPoul-Henning Kamp static void
13031304807SPoul-Henning Kamp EndElement(void *userData, const char *name __unused)
13131304807SPoul-Henning Kamp {
13231304807SPoul-Henning Kamp 	struct mytree *mt;
13331304807SPoul-Henning Kamp 	struct node *np;
13431304807SPoul-Henning Kamp 
13531304807SPoul-Henning Kamp 	mt = userData;
1366de2a2e8SPoul-Henning Kamp 	if (mt->ignore)
1376de2a2e8SPoul-Henning Kamp 		return;
13831304807SPoul-Henning Kamp 
13931304807SPoul-Henning Kamp 	mt->indent -= 2;
14031304807SPoul-Henning Kamp 	sbuf_finish(mt->cur->cont);
14131304807SPoul-Henning Kamp 	LIST_FOREACH(np, &mt->cur->children, siblings) {
14231304807SPoul-Henning Kamp 		if (strcmp(np->name, "name"))
14331304807SPoul-Henning Kamp 			continue;
14431304807SPoul-Henning Kamp 		sbuf_cat(mt->cur->key, sbuf_data(np->cont));
14531304807SPoul-Henning Kamp 		break;
14631304807SPoul-Henning Kamp 	}
14731304807SPoul-Henning Kamp 	sbuf_finish(mt->cur->key);
14831304807SPoul-Henning Kamp 	mt->cur = mt->cur->parent;
14931304807SPoul-Henning Kamp }
15031304807SPoul-Henning Kamp 
15131304807SPoul-Henning Kamp static void
15231304807SPoul-Henning Kamp CharData(void *userData , const XML_Char *s , int len)
15331304807SPoul-Henning Kamp {
15431304807SPoul-Henning Kamp 	struct mytree *mt;
15531304807SPoul-Henning Kamp 	const char *b, *e;
15631304807SPoul-Henning Kamp 
15731304807SPoul-Henning Kamp 	mt = userData;
1586de2a2e8SPoul-Henning Kamp 	if (mt->ignore)
1596de2a2e8SPoul-Henning Kamp 		return;
16031304807SPoul-Henning Kamp 	b = s;
16131304807SPoul-Henning Kamp 	e = s + len - 1;
16231304807SPoul-Henning Kamp 	while (isspace(*b) && b < e)
16331304807SPoul-Henning Kamp 		b++;
16431304807SPoul-Henning Kamp 	while (isspace(*e) && e > b)
16531304807SPoul-Henning Kamp 		e--;
16631304807SPoul-Henning Kamp 	if (e != b)
16731304807SPoul-Henning Kamp 		sbuf_bcat(mt->cur->cont, b, e - b + 1);
16831304807SPoul-Henning Kamp }
16931304807SPoul-Henning Kamp 
17031304807SPoul-Henning Kamp static struct mytree *
17131304807SPoul-Henning Kamp dofile(char *filename)
17231304807SPoul-Henning Kamp {
17331304807SPoul-Henning Kamp 	XML_Parser parser;
17431304807SPoul-Henning Kamp 	struct mytree *mt;
17531304807SPoul-Henning Kamp 	struct stat st;
17631304807SPoul-Henning Kamp 	int fd;
17731304807SPoul-Henning Kamp 	char *p;
17831304807SPoul-Henning Kamp 	int i;
17931304807SPoul-Henning Kamp 
18031304807SPoul-Henning Kamp 	parser = XML_ParserCreate(NULL);
18131304807SPoul-Henning Kamp 	mt = calloc(1, sizeof *mt);
18231304807SPoul-Henning Kamp 	mt->top = new_node();
18331304807SPoul-Henning Kamp 	mt->top->name = "(top)";
18431304807SPoul-Henning Kamp 	mt->top->parent = mt->top;
18531304807SPoul-Henning Kamp 	mt->cur = mt->top;
18631304807SPoul-Henning Kamp 	sbuf_finish(mt->top->key);
18731304807SPoul-Henning Kamp 	sbuf_finish(mt->top->cont);
18831304807SPoul-Henning Kamp 	XML_SetUserData(parser, mt);
18931304807SPoul-Henning Kamp 	XML_SetElementHandler(parser, StartElement, EndElement);
19031304807SPoul-Henning Kamp 	XML_SetCharacterDataHandler(parser, CharData);
19131304807SPoul-Henning Kamp 	fd = open(filename, O_RDONLY);
19231304807SPoul-Henning Kamp 	if (fd < 0)
19331304807SPoul-Henning Kamp 		err(1, filename);
19431304807SPoul-Henning Kamp 	fstat(fd, &st);
19531304807SPoul-Henning Kamp 	p = mmap(NULL, st.st_size, PROT_READ, MAP_NOCORE|MAP_PRIVATE, fd, 0);
19631304807SPoul-Henning Kamp 	i = XML_Parse(parser, p, st.st_size, 1);
1976de2a2e8SPoul-Henning Kamp 	if (i != 1)
1986de2a2e8SPoul-Henning Kamp 		errx(1, "XML_Parse complained -> %d", i);
19931304807SPoul-Henning Kamp 	munmap(p, st.st_size);
20031304807SPoul-Henning Kamp 	close(fd);
20131304807SPoul-Henning Kamp 	XML_ParserFree(parser);
20231304807SPoul-Henning Kamp 	sbuf_finish(mt->top->cont);
20331304807SPoul-Henning Kamp 	if (i)
20431304807SPoul-Henning Kamp 		return (mt);
20531304807SPoul-Henning Kamp 	else
20631304807SPoul-Henning Kamp 		return (NULL);
20731304807SPoul-Henning Kamp }
20831304807SPoul-Henning Kamp 
20931304807SPoul-Henning Kamp static void
21031304807SPoul-Henning Kamp print_node(struct node *np)
21131304807SPoul-Henning Kamp {
21200d1e0f6SPoul-Henning Kamp 	printf("\"%s\" -- \"%s\" -- \"%s\"", np->name, sbuf_data(np->cont), sbuf_data(np->key));
21300d1e0f6SPoul-Henning Kamp 	if (np->id)
21400d1e0f6SPoul-Henning Kamp 		printf(" id=\"%s\"", np->id);
21500d1e0f6SPoul-Henning Kamp 	if (np->ref)
21600d1e0f6SPoul-Henning Kamp 		printf(" ref=\"%s\"", np->ref);
21700d1e0f6SPoul-Henning Kamp 	printf("\n");
21800d1e0f6SPoul-Henning Kamp }
21900d1e0f6SPoul-Henning Kamp 
22000d1e0f6SPoul-Henning Kamp static void
22100d1e0f6SPoul-Henning Kamp print_tree(struct node *np, int n)
22200d1e0f6SPoul-Henning Kamp {
22300d1e0f6SPoul-Henning Kamp 	struct node *np1;
22400d1e0f6SPoul-Henning Kamp 
22500d1e0f6SPoul-Henning Kamp 	indent(n); printf("%s id=%s ref=%s\n", np->name, np->id, np->ref);
22600d1e0f6SPoul-Henning Kamp 	LIST_FOREACH(np1, &np->children, siblings)
22700d1e0f6SPoul-Henning Kamp 		print_tree(np1, n + 2);
22831304807SPoul-Henning Kamp }
22931304807SPoul-Henning Kamp 
23031304807SPoul-Henning Kamp static void
23131304807SPoul-Henning Kamp sort_node(struct node *np)
23231304807SPoul-Henning Kamp {
23331304807SPoul-Henning Kamp 	struct node *np1, *np2;
23431304807SPoul-Henning Kamp 	int n;
23531304807SPoul-Henning Kamp 
23631304807SPoul-Henning Kamp 	LIST_FOREACH(np1, &np->children, siblings)
23731304807SPoul-Henning Kamp 		sort_node(np1);
23831304807SPoul-Henning Kamp 	do {
23931304807SPoul-Henning Kamp 		np1 = LIST_FIRST(&np->children);
24031304807SPoul-Henning Kamp 		n = 0;
24131304807SPoul-Henning Kamp 		for (;;) {
24231304807SPoul-Henning Kamp 			if (np1 == NULL)
24331304807SPoul-Henning Kamp 				return;
24431304807SPoul-Henning Kamp 			np2 = LIST_NEXT(np1, siblings);
24531304807SPoul-Henning Kamp 			if (np2 == NULL)
24631304807SPoul-Henning Kamp 				return;
24731304807SPoul-Henning Kamp 			if (strcmp(sbuf_data(np1->key), sbuf_data(np2->key)) > 0) {
24831304807SPoul-Henning Kamp 				LIST_REMOVE(np2, siblings);
24931304807SPoul-Henning Kamp 				LIST_INSERT_BEFORE(np1, np2, siblings);
25031304807SPoul-Henning Kamp 				n++;
25131304807SPoul-Henning Kamp 				break;
25231304807SPoul-Henning Kamp 			}
25331304807SPoul-Henning Kamp 			np1 = np2;
25431304807SPoul-Henning Kamp 		}
25531304807SPoul-Henning Kamp 	} while (n);
25631304807SPoul-Henning Kamp }
25731304807SPoul-Henning Kamp 
25831304807SPoul-Henning Kamp static int
25931304807SPoul-Henning Kamp refcmp(char *r1, char *r2)
26031304807SPoul-Henning Kamp {
26131304807SPoul-Henning Kamp 	struct ref *r;
26231304807SPoul-Henning Kamp 
26331304807SPoul-Henning Kamp 	LIST_FOREACH(r, &refs, next) {
26431304807SPoul-Henning Kamp 		if (!strcmp(r1, r->k1))
26531304807SPoul-Henning Kamp 			return (strcmp(r2, r->k2));
26631304807SPoul-Henning Kamp 	}
26731304807SPoul-Henning Kamp 	r = calloc(1, sizeof(*r));
26831304807SPoul-Henning Kamp 	r->k1 = strdup(r1);
26931304807SPoul-Henning Kamp 	r->k2 = strdup(r2);
27031304807SPoul-Henning Kamp 	LIST_INSERT_HEAD(&refs, r, next);
271a99aa4c4SPoul-Henning Kamp 	if (fsubs != NULL) {
272a99aa4c4SPoul-Henning Kamp 		fprintf(fsubs, "s/%s/%s/g\n", r1, r2);
273a99aa4c4SPoul-Henning Kamp 		fflush(fsubs);
274a99aa4c4SPoul-Henning Kamp 	}
27531304807SPoul-Henning Kamp 	return (0);
27631304807SPoul-Henning Kamp }
27731304807SPoul-Henning Kamp 
27831304807SPoul-Henning Kamp static int compare_node2(struct node *n1, struct node *n2, int in);
27931304807SPoul-Henning Kamp 
28031304807SPoul-Henning Kamp static int
28131304807SPoul-Henning Kamp compare_node(struct node *n1, struct node *n2, int in)
28231304807SPoul-Henning Kamp {
28331304807SPoul-Henning Kamp 	int i;
28431304807SPoul-Henning Kamp 	struct node *n1a, *n2a;
28531304807SPoul-Henning Kamp 
28631304807SPoul-Henning Kamp 	i = strcmp(n1->name, n2->name);
28731304807SPoul-Henning Kamp 	if (i)
28831304807SPoul-Henning Kamp 		return (i);
28900d1e0f6SPoul-Henning Kamp 	if (n1->id && n2->id)
29000d1e0f6SPoul-Henning Kamp 		i = refcmp(n1->id, n2->id);
29100d1e0f6SPoul-Henning Kamp 	else if (n1->id || n2->id)
29200d1e0f6SPoul-Henning Kamp 		i = -1;
29300d1e0f6SPoul-Henning Kamp 	if (i)
29400d1e0f6SPoul-Henning Kamp 		return (i);
29500d1e0f6SPoul-Henning Kamp 	if (n1->ref && n2->ref)
29600d1e0f6SPoul-Henning Kamp 		i = refcmp(n1->ref, n2->ref);
29700d1e0f6SPoul-Henning Kamp 	else if (n1->ref || n2->ref)
29800d1e0f6SPoul-Henning Kamp 		i = -1;
29900d1e0f6SPoul-Henning Kamp 	if (i)
30000d1e0f6SPoul-Henning Kamp 		return (i);
30131304807SPoul-Henning Kamp 	if (!strcmp(n1->name, "ref"))
30231304807SPoul-Henning Kamp 		i = refcmp(sbuf_data(n1->cont), sbuf_data(n2->cont));
30331304807SPoul-Henning Kamp 	else
30431304807SPoul-Henning Kamp 		i = strcmp(sbuf_data(n1->cont), sbuf_data(n2->cont));
30531304807SPoul-Henning Kamp 	if (i)
30631304807SPoul-Henning Kamp 		return (1);
30731304807SPoul-Henning Kamp 	n1a = LIST_FIRST(&n1->children);
30831304807SPoul-Henning Kamp 	n2a = LIST_FIRST(&n2->children);
30931304807SPoul-Henning Kamp 	for (;;) {
31031304807SPoul-Henning Kamp 		if (n1a == NULL && n2a == NULL)
31131304807SPoul-Henning Kamp 			return (0);
312fdc34af0SPoul-Henning Kamp 		if (n1a != NULL && n2a == NULL) {
313fdc34af0SPoul-Henning Kamp 			printf("1>");
314fdc34af0SPoul-Henning Kamp 			indent(in);
315fdc34af0SPoul-Henning Kamp 			print_node(n1a);
316fdc34af0SPoul-Henning Kamp 			printf("2>\n");
31731304807SPoul-Henning Kamp 			return (1);
318fdc34af0SPoul-Henning Kamp 		}
319fdc34af0SPoul-Henning Kamp 		if (n1a == NULL && n2a != NULL) {
320fdc34af0SPoul-Henning Kamp 			printf("1>\n");
321fdc34af0SPoul-Henning Kamp 			printf("2>");
322fdc34af0SPoul-Henning Kamp 			indent(in);
323fdc34af0SPoul-Henning Kamp 			print_node(n2a);
32431304807SPoul-Henning Kamp 			return (1);
325fdc34af0SPoul-Henning Kamp 		}
32631304807SPoul-Henning Kamp 		i = compare_node2(n1a, n2a, in + 2);
32731304807SPoul-Henning Kamp 		if (i)
32831304807SPoul-Henning Kamp 			return (1);
32931304807SPoul-Henning Kamp 		n1a = LIST_NEXT(n1a, siblings);
33031304807SPoul-Henning Kamp 		n2a = LIST_NEXT(n2a, siblings);
33131304807SPoul-Henning Kamp 	}
33231304807SPoul-Henning Kamp 	return (0);
33331304807SPoul-Henning Kamp }
33431304807SPoul-Henning Kamp 
33531304807SPoul-Henning Kamp static int
33631304807SPoul-Henning Kamp compare_node2(struct node *n1, struct node *n2, int in)
33731304807SPoul-Henning Kamp {
33831304807SPoul-Henning Kamp 	int i;
33931304807SPoul-Henning Kamp 
34031304807SPoul-Henning Kamp 	i = compare_node(n1, n2, in);
34131304807SPoul-Henning Kamp 	if (i) {
34231304807SPoul-Henning Kamp 		printf("1>");
34331304807SPoul-Henning Kamp 		indent(in);
34431304807SPoul-Henning Kamp 		print_node(n1);
34531304807SPoul-Henning Kamp 		printf("2>");
34631304807SPoul-Henning Kamp 		indent(in);
34731304807SPoul-Henning Kamp 		print_node(n2);
34831304807SPoul-Henning Kamp 	}
34931304807SPoul-Henning Kamp 	return (i);
35031304807SPoul-Henning Kamp }
35131304807SPoul-Henning Kamp 
35231304807SPoul-Henning Kamp 
35331304807SPoul-Henning Kamp 
35431304807SPoul-Henning Kamp int
35531304807SPoul-Henning Kamp main(int argc, char **argv)
35631304807SPoul-Henning Kamp {
35731304807SPoul-Henning Kamp 	struct mytree *t1, *t2;
35831304807SPoul-Henning Kamp 	int i;
35931304807SPoul-Henning Kamp 
360a99aa4c4SPoul-Henning Kamp 	fsubs = fopen("_.subs", "w");
36131304807SPoul-Henning Kamp 	setbuf(stdout, NULL);
36231304807SPoul-Henning Kamp 	setbuf(stderr, NULL);
36331304807SPoul-Henning Kamp 	if (argc != 3)
364d3974088SDag-Erling Smørgrav 		errx(1, "usage: %s file1 file2", argv[0]);
36531304807SPoul-Henning Kamp 
36631304807SPoul-Henning Kamp 	t1 = dofile(argv[1]);
36731304807SPoul-Henning Kamp 	if (t1 == NULL)
36831304807SPoul-Henning Kamp 		errx(2, "XML parser error on file %s", argv[1]);
36931304807SPoul-Henning Kamp 	sort_node(t1->top);
37031304807SPoul-Henning Kamp 	t2 = dofile(argv[2]);
37131304807SPoul-Henning Kamp 	if (t2 == NULL)
37231304807SPoul-Henning Kamp 		errx(2, "XML parser error on file %s", argv[2]);
37331304807SPoul-Henning Kamp 	sort_node(t2->top);
37431304807SPoul-Henning Kamp 	i = compare_node(t1->top, t2->top, 0);
37531304807SPoul-Henning Kamp 	return (i);
37631304807SPoul-Henning Kamp }
37731304807SPoul-Henning Kamp 
378