xref: /minix3/usr.bin/infocmp/infocmp.c (revision 84d9c625bfea59e274550651111ae9edfdc40fbd)
1*84d9c625SLionel Sambuc /* $NetBSD: infocmp.c,v 1.8 2013/10/01 09:01:49 roy Exp $ */
25139afeeSAntoine Leca 
35139afeeSAntoine Leca /*
45139afeeSAntoine Leca  * Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
55139afeeSAntoine Leca  *
65139afeeSAntoine Leca  * This code is derived from software contributed to The NetBSD Foundation
75139afeeSAntoine Leca  * by Roy Marples.
85139afeeSAntoine Leca  *
95139afeeSAntoine Leca  * Redistribution and use in source and binary forms, with or without
105139afeeSAntoine Leca  * modification, are permitted provided that the following conditions
115139afeeSAntoine Leca  * are met:
125139afeeSAntoine Leca  * 1. Redistributions of source code must retain the above copyright
135139afeeSAntoine Leca  *    notice, this list of conditions and the following disclaimer.
145139afeeSAntoine Leca  * 2. Redistributions in binary form must reproduce the above copyright
155139afeeSAntoine Leca  *    notice, this list of conditions and the following disclaimer in the
165139afeeSAntoine Leca  *    documentation and/or other materials provided with the distribution.
175139afeeSAntoine Leca  *
185139afeeSAntoine Leca  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
195139afeeSAntoine Leca  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
205139afeeSAntoine Leca  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
215139afeeSAntoine Leca  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
225139afeeSAntoine Leca  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
235139afeeSAntoine Leca  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
245139afeeSAntoine Leca  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
255139afeeSAntoine Leca  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
265139afeeSAntoine Leca  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
275139afeeSAntoine Leca  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
285139afeeSAntoine Leca  */
295139afeeSAntoine Leca 
305139afeeSAntoine Leca #include <sys/cdefs.h>
31*84d9c625SLionel Sambuc __RCSID("$NetBSD: infocmp.c,v 1.8 2013/10/01 09:01:49 roy Exp $");
325139afeeSAntoine Leca 
335139afeeSAntoine Leca #include <sys/ioctl.h>
345139afeeSAntoine Leca 
355139afeeSAntoine Leca #include <ctype.h>
365139afeeSAntoine Leca #include <err.h>
375139afeeSAntoine Leca #include <stdio.h>
385139afeeSAntoine Leca #include <stdlib.h>
395139afeeSAntoine Leca #include <string.h>
405139afeeSAntoine Leca #include <term_private.h>
415139afeeSAntoine Leca #include <term.h>
425139afeeSAntoine Leca #include <unistd.h>
435139afeeSAntoine Leca 
445139afeeSAntoine Leca #define SW 8
455139afeeSAntoine Leca 
465139afeeSAntoine Leca typedef struct tient {
475139afeeSAntoine Leca 	char type;
485139afeeSAntoine Leca 	const char *id;
495139afeeSAntoine Leca 	signed char flag;
505139afeeSAntoine Leca 	short num;
515139afeeSAntoine Leca 	const char *str;
525139afeeSAntoine Leca } TIENT;
535139afeeSAntoine Leca 
545139afeeSAntoine Leca static size_t cols;
555139afeeSAntoine Leca static int aflag, cflag, nflag, qflag, xflag;
565139afeeSAntoine Leca 
575139afeeSAntoine Leca static size_t
outstr(FILE * f,const char * str)585139afeeSAntoine Leca outstr(FILE *f, const char *str)
595139afeeSAntoine Leca {
605139afeeSAntoine Leca 	unsigned char ch;
615139afeeSAntoine Leca 	size_t r, l;
625139afeeSAntoine Leca 
635139afeeSAntoine Leca 	r = 0;
645139afeeSAntoine Leca 	l = strlen(str);
655139afeeSAntoine Leca 	while ((ch = (unsigned char)(*str++)) != '\0') {
665139afeeSAntoine Leca 		switch (ch) {
675139afeeSAntoine Leca 		case 128:
685139afeeSAntoine Leca 			ch = '0';
695139afeeSAntoine Leca 			break;
705139afeeSAntoine Leca 		case '\033':
715139afeeSAntoine Leca 			ch = 'E';
725139afeeSAntoine Leca 			break;
735139afeeSAntoine Leca 		case '\014':
745139afeeSAntoine Leca 			ch = 'f';
755139afeeSAntoine Leca 			break;
765139afeeSAntoine Leca 		case '^': /* FALLTHROUGH */
775139afeeSAntoine Leca 		case ',': /* escape these */
785139afeeSAntoine Leca 			break;
795139afeeSAntoine Leca 		case ' ':
805139afeeSAntoine Leca 			ch = 's';
815139afeeSAntoine Leca 			break;
825139afeeSAntoine Leca 		default:
835139afeeSAntoine Leca 			if (ch == '\177') {
845139afeeSAntoine Leca 				if (f != NULL)
855139afeeSAntoine Leca 					fputc('^', f);
865139afeeSAntoine Leca 				ch = '?';
875139afeeSAntoine Leca 				r++;
885139afeeSAntoine Leca 			} else if (iscntrl(ch) &&
895139afeeSAntoine Leca 			    ch < 128 &&
905139afeeSAntoine Leca 			    ch != '\\' &&
915139afeeSAntoine Leca 			    (l < 4 || isdigit((unsigned char)*str)))
925139afeeSAntoine Leca 			{
935139afeeSAntoine Leca 				if (f != NULL)
945139afeeSAntoine Leca 					fputc('^', f);
955139afeeSAntoine Leca 				ch += '@';
965139afeeSAntoine Leca 				r++;
975139afeeSAntoine Leca 			} else if (!isprint(ch)) {
985139afeeSAntoine Leca 				if (f != NULL)
995139afeeSAntoine Leca 					fprintf(f, "\\%03o", ch);
1005139afeeSAntoine Leca 				r += 4;
1015139afeeSAntoine Leca 				continue;
1025139afeeSAntoine Leca 			}
1035139afeeSAntoine Leca 			goto prnt;
1045139afeeSAntoine Leca 		}
1055139afeeSAntoine Leca 
1065139afeeSAntoine Leca 		if (f != NULL)
1075139afeeSAntoine Leca 			fputc('\\', f);
1085139afeeSAntoine Leca 		r++;
1095139afeeSAntoine Leca prnt:
1105139afeeSAntoine Leca 		if (f != NULL)
1115139afeeSAntoine Leca 			fputc(ch, f);
1125139afeeSAntoine Leca 		r++;
1135139afeeSAntoine Leca 	}
1145139afeeSAntoine Leca 	return r;
1155139afeeSAntoine Leca }
1165139afeeSAntoine Leca 
1175139afeeSAntoine Leca static int
ent_compare(const void * a,const void * b)1185139afeeSAntoine Leca ent_compare(const void *a, const void *b)
1195139afeeSAntoine Leca {
1205139afeeSAntoine Leca 	const TIENT *ta, *tb;
1215139afeeSAntoine Leca 
1225139afeeSAntoine Leca 	ta = (const TIENT *)a;
1235139afeeSAntoine Leca 	tb = (const TIENT *)b;
1245139afeeSAntoine Leca 	return strcmp(ta->id, tb->id);
1255139afeeSAntoine Leca }
1265139afeeSAntoine Leca 
1275139afeeSAntoine Leca static void
setdb(char * db)1285139afeeSAntoine Leca setdb(char *db)
1295139afeeSAntoine Leca {
1305139afeeSAntoine Leca 	size_t len;
1315139afeeSAntoine Leca 
1325139afeeSAntoine Leca 	len = strlen(db);
1335139afeeSAntoine Leca 	if (len > 3 &&
1345139afeeSAntoine Leca 	    db[len - 3] == '.' &&
1355139afeeSAntoine Leca 	    db[len - 2] == 'd' &&
1365139afeeSAntoine Leca 	    db[len - 1] == 'b')
1375139afeeSAntoine Leca 		db[len - 3] = '\0';
1385139afeeSAntoine Leca 	setenv("TERMINFO", db, 1);
1395139afeeSAntoine Leca }
1405139afeeSAntoine Leca 
1415139afeeSAntoine Leca static void
print_ent(const TIENT * ents,size_t nents)1425139afeeSAntoine Leca print_ent(const TIENT *ents, size_t nents)
1435139afeeSAntoine Leca {
1445139afeeSAntoine Leca 	size_t col, i, l;
1455139afeeSAntoine Leca 	char nbuf[64];
1465139afeeSAntoine Leca 
1475139afeeSAntoine Leca 	if (nents == 0)
1485139afeeSAntoine Leca 		return;
1495139afeeSAntoine Leca 
1505139afeeSAntoine Leca 	col = SW;
1515139afeeSAntoine Leca 	printf("\t");
1525139afeeSAntoine Leca 	for (i = 0; i < nents; i++) {
1535139afeeSAntoine Leca 		if (*ents[i].id == '.' && aflag == 0)
1545139afeeSAntoine Leca 			continue;
1555139afeeSAntoine Leca 		switch (ents[i].type) {
1565139afeeSAntoine Leca 		case 'f':
1575139afeeSAntoine Leca 			if (ents[i].flag == ABSENT_BOOLEAN)
1585139afeeSAntoine Leca 				continue;
1595139afeeSAntoine Leca 			l = strlen(ents[i].id) + 2;
1605139afeeSAntoine Leca 			if (ents[i].flag == CANCELLED_BOOLEAN)
1615139afeeSAntoine Leca 				l++;
1625139afeeSAntoine Leca 			break;
1635139afeeSAntoine Leca 		case 'n':
1645139afeeSAntoine Leca 			if (ents[i].num == ABSENT_NUMERIC)
1655139afeeSAntoine Leca 				continue;
1665139afeeSAntoine Leca 			if (VALID_NUMERIC(ents[i].num))
1675139afeeSAntoine Leca 				l = snprintf(nbuf, sizeof(nbuf), "%s#%d,",
1685139afeeSAntoine Leca 				    ents[i].id, ents[i].num);
1695139afeeSAntoine Leca 			else
1705139afeeSAntoine Leca 				l = snprintf(nbuf, sizeof(nbuf), "%s@,",
1715139afeeSAntoine Leca 				    ents[i].id);
1725139afeeSAntoine Leca 			break;
1735139afeeSAntoine Leca 		case 's':
1745139afeeSAntoine Leca 			if (ents[i].str == ABSENT_STRING)
1755139afeeSAntoine Leca 				continue;
1765139afeeSAntoine Leca 			if (VALID_STRING(ents[i].str))
1775139afeeSAntoine Leca 				l = strlen(ents[i].id) +
1785139afeeSAntoine Leca 				    outstr(NULL, ents[i].str) + 7;
1795139afeeSAntoine Leca 			else
1805139afeeSAntoine Leca 				l = strlen(ents[i].id) + 3;
1815139afeeSAntoine Leca 			break;
1825139afeeSAntoine Leca 		default:
1835139afeeSAntoine Leca 			errx(1, "invalid type");
1845139afeeSAntoine Leca 		}
1855139afeeSAntoine Leca 		if (col != SW) {
1865139afeeSAntoine Leca 			if (col + l > cols) {
1875139afeeSAntoine Leca 				printf("\n\t");
1885139afeeSAntoine Leca 				col = SW;
1895139afeeSAntoine Leca 			} else
1905139afeeSAntoine Leca 				col += printf(" ");
1915139afeeSAntoine Leca 		}
1925139afeeSAntoine Leca 		switch (ents[i].type) {
1935139afeeSAntoine Leca 		case 'f':
1945139afeeSAntoine Leca 			col += printf("%s", ents[i].id);
1955139afeeSAntoine Leca 			if (ents[i].flag == ABSENT_BOOLEAN ||
1965139afeeSAntoine Leca 			    ents[i].flag == CANCELLED_BOOLEAN)
1975139afeeSAntoine Leca 				col += printf("@");
1985139afeeSAntoine Leca 			col += printf(",");
1995139afeeSAntoine Leca 			break;
2005139afeeSAntoine Leca 		case 'n':
2015139afeeSAntoine Leca 			col += printf("%s", nbuf);
2025139afeeSAntoine Leca 			break;
2035139afeeSAntoine Leca 		case 's':
2045139afeeSAntoine Leca 			col += printf("%s", ents[i].id);
2055139afeeSAntoine Leca 			if (VALID_STRING(ents[i].str)) {
2065139afeeSAntoine Leca 				col += printf("=");
2075139afeeSAntoine Leca 				col += outstr(stdout, ents[i].str);
2085139afeeSAntoine Leca 			} else
2095139afeeSAntoine Leca 				col += printf("@");
2105139afeeSAntoine Leca 			col += printf(",");
2115139afeeSAntoine Leca 			break;
2125139afeeSAntoine Leca 		}
2135139afeeSAntoine Leca 	}
2145139afeeSAntoine Leca 	printf("\n");
2155139afeeSAntoine Leca }
2165139afeeSAntoine Leca 
2175139afeeSAntoine Leca static size_t
load_ents(TIENT * ents,TERMINAL * t,char type)2185139afeeSAntoine Leca load_ents(TIENT *ents, TERMINAL *t, char type)
2195139afeeSAntoine Leca {
2205139afeeSAntoine Leca 	size_t i, n, max;
2215139afeeSAntoine Leca 	TERMUSERDEF *ud;
2225139afeeSAntoine Leca 
2235139afeeSAntoine Leca 	switch (type) {
2245139afeeSAntoine Leca 	case 'f':
2255139afeeSAntoine Leca 		max = TIFLAGMAX;
2265139afeeSAntoine Leca 		break;
2275139afeeSAntoine Leca 	case 'n':
2285139afeeSAntoine Leca 		max = TINUMMAX;
2295139afeeSAntoine Leca 		break;
2305139afeeSAntoine Leca 	default:
2315139afeeSAntoine Leca 		max = TISTRMAX;
2325139afeeSAntoine Leca 	}
2335139afeeSAntoine Leca 
2345139afeeSAntoine Leca 	n = 0;
2355139afeeSAntoine Leca 	for (i = 0; i <= max; i++) {
2365139afeeSAntoine Leca 		switch (type) {
2375139afeeSAntoine Leca 		case 'f':
2385139afeeSAntoine Leca 			if (t->flags[i] == 1 ||
2395139afeeSAntoine Leca 			    (aflag && t->flags[i] == CANCELLED_BOOLEAN))
2405139afeeSAntoine Leca 			{
2415139afeeSAntoine Leca 				ents[n].id = _ti_flagid(i);
2425139afeeSAntoine Leca 				ents[n].type = 'f';
2435139afeeSAntoine Leca 				ents[n++].flag = t->flags[i];
2445139afeeSAntoine Leca 			}
2455139afeeSAntoine Leca 			break;
2465139afeeSAntoine Leca 		case 'n':
2475139afeeSAntoine Leca 			if (VALID_NUMERIC(t->nums[i]) ||
2485139afeeSAntoine Leca 			    (aflag && t->nums[i] == CANCELLED_NUMERIC))
2495139afeeSAntoine Leca 			{
2505139afeeSAntoine Leca 				ents[n].id = _ti_numid(i);
2515139afeeSAntoine Leca 				ents[n].type = 'n';
2525139afeeSAntoine Leca 				ents[n++].num = t->nums[i];
2535139afeeSAntoine Leca 			}
2545139afeeSAntoine Leca 			break;
2555139afeeSAntoine Leca 		default:
2565139afeeSAntoine Leca 			if (VALID_STRING(t->strs[i]) ||
2575139afeeSAntoine Leca 			    (aflag && t->strs[i] == CANCELLED_STRING))
2585139afeeSAntoine Leca 			{
2595139afeeSAntoine Leca 				ents[n].id = _ti_strid(i);
2605139afeeSAntoine Leca 				ents[n].type = 's';
2615139afeeSAntoine Leca 				ents[n++].str = t->strs[i];
2625139afeeSAntoine Leca 			}
2635139afeeSAntoine Leca 			break;
2645139afeeSAntoine Leca 		}
2655139afeeSAntoine Leca 	}
2665139afeeSAntoine Leca 
2675139afeeSAntoine Leca 	if (xflag != 0 && t->_nuserdefs != 0) {
2685139afeeSAntoine Leca 		for (i = 0; i < t->_nuserdefs; i++) {
2695139afeeSAntoine Leca 			ud = &t->_userdefs[i];
2705139afeeSAntoine Leca 			if (ud->type == type) {
2715139afeeSAntoine Leca 				switch (type) {
2725139afeeSAntoine Leca 				case 'f':
2735139afeeSAntoine Leca 					if (!aflag &&
2745139afeeSAntoine Leca 					    !VALID_BOOLEAN(ud->flag))
2755139afeeSAntoine Leca 						continue;
2765139afeeSAntoine Leca 					break;
2775139afeeSAntoine Leca 				case 'n':
2785139afeeSAntoine Leca 					if (!aflag &&
2795139afeeSAntoine Leca 					    !VALID_NUMERIC(ud->num))
2805139afeeSAntoine Leca 						continue;
2815139afeeSAntoine Leca 					break;
2825139afeeSAntoine Leca 				case 's':
2835139afeeSAntoine Leca 					if (!aflag &&
2845139afeeSAntoine Leca 					    !VALID_STRING(ud->str))
2855139afeeSAntoine Leca 						continue;
2865139afeeSAntoine Leca 					break;
2875139afeeSAntoine Leca 				}
2885139afeeSAntoine Leca 				ents[n].id = ud->id;
2895139afeeSAntoine Leca 				ents[n].type = ud->type;
2905139afeeSAntoine Leca 				ents[n].flag = ud->flag;
2915139afeeSAntoine Leca 				ents[n].num = ud->num;
2925139afeeSAntoine Leca 				ents[n++].str = ud->str;
2935139afeeSAntoine Leca 			}
2945139afeeSAntoine Leca 		}
2955139afeeSAntoine Leca 	}
2965139afeeSAntoine Leca 
2975139afeeSAntoine Leca 	qsort(ents, n, sizeof(TIENT), ent_compare);
2985139afeeSAntoine Leca 	return n;
2995139afeeSAntoine Leca }
3005139afeeSAntoine Leca 
3015139afeeSAntoine Leca static void
cprint_ent(TIENT * ent)3025139afeeSAntoine Leca cprint_ent(TIENT *ent)
3035139afeeSAntoine Leca {
3045139afeeSAntoine Leca 
3055139afeeSAntoine Leca 	if (ent == NULL) {
3065139afeeSAntoine Leca 		if (qflag == 0)
3075139afeeSAntoine Leca 			printf("NULL");
3085139afeeSAntoine Leca 		else
3095139afeeSAntoine Leca 			printf("-");
3105139afeeSAntoine Leca 	}
3115139afeeSAntoine Leca 
3125139afeeSAntoine Leca 	switch (ent->type) {
3135139afeeSAntoine Leca 	case 'f':
3145139afeeSAntoine Leca 		if (VALID_BOOLEAN(ent->flag))
3155139afeeSAntoine Leca 			printf(ent->flag == 1 ? "T" : "F");
3165139afeeSAntoine Leca 		else if (qflag == 0)
3175139afeeSAntoine Leca 			printf("F");
3185139afeeSAntoine Leca 		else if (ent->flag == CANCELLED_BOOLEAN)
3195139afeeSAntoine Leca 			printf("@");
3205139afeeSAntoine Leca 		else
3215139afeeSAntoine Leca 			printf("-");
3225139afeeSAntoine Leca 		break;
3235139afeeSAntoine Leca 	case 'n':
3245139afeeSAntoine Leca 		if (VALID_NUMERIC(ent->num))
3255139afeeSAntoine Leca 			printf("%d", ent->num);
3265139afeeSAntoine Leca 		else if (qflag == 0)
3275139afeeSAntoine Leca 			printf("NULL");
3285139afeeSAntoine Leca 		else if (ent->num == CANCELLED_NUMERIC)
3295139afeeSAntoine Leca 			printf("@");
3305139afeeSAntoine Leca 		else
3315139afeeSAntoine Leca 			printf("-");
3325139afeeSAntoine Leca 		break;
3335139afeeSAntoine Leca 	case 's':
3345139afeeSAntoine Leca 		if (VALID_STRING(ent->str)) {
3355139afeeSAntoine Leca 			printf("'");
3365139afeeSAntoine Leca 			outstr(stdout, ent->str);
3375139afeeSAntoine Leca 			printf("'");
3385139afeeSAntoine Leca 		} else if (qflag == 0)
3395139afeeSAntoine Leca 			printf("NULL");
3405139afeeSAntoine Leca 		else if (ent->str == CANCELLED_STRING)
3415139afeeSAntoine Leca 			printf("@");
3425139afeeSAntoine Leca 		else
3435139afeeSAntoine Leca 			printf("-");
3445139afeeSAntoine Leca 		break;
3455139afeeSAntoine Leca 	}
3465139afeeSAntoine Leca }
3475139afeeSAntoine Leca 
3485139afeeSAntoine Leca static void
compare_ents(TIENT * ents1,size_t n1,TIENT * ents2,size_t n2)3495139afeeSAntoine Leca compare_ents(TIENT *ents1, size_t n1, TIENT *ents2, size_t n2)
3505139afeeSAntoine Leca {
3515139afeeSAntoine Leca 	size_t i1, i2;
3525139afeeSAntoine Leca 	TIENT *e1, *e2, ee;
3535139afeeSAntoine Leca 	int c;
3545139afeeSAntoine Leca 
3555139afeeSAntoine Leca 	i1 = i2 = 0;
3565139afeeSAntoine Leca 	ee.type = 'f';
3575139afeeSAntoine Leca 	ee.flag = ABSENT_BOOLEAN;
3585139afeeSAntoine Leca 	ee.num = ABSENT_NUMERIC;
3595139afeeSAntoine Leca 	ee.str = ABSENT_STRING;
3605139afeeSAntoine Leca 	while (i1 != n1 || i2 != n2) {
3615139afeeSAntoine Leca 		if (i1 == n1)
3625139afeeSAntoine Leca 			c = 1;
3635139afeeSAntoine Leca 		else if (i2 == n2)
3645139afeeSAntoine Leca 			c = -1;
3655139afeeSAntoine Leca 		else
3665139afeeSAntoine Leca 			c = strcmp(ents1[i1].id, ents2[i2].id);
3675139afeeSAntoine Leca 		if (c == 0) {
3685139afeeSAntoine Leca 			e1 = &ents1[i1++];
3695139afeeSAntoine Leca 			e2 = &ents2[i2++];
3705139afeeSAntoine Leca 		} else if (c < 0) {
3715139afeeSAntoine Leca 			e1 = &ents1[i1++];
3725139afeeSAntoine Leca 			e2 = &ee;
3735139afeeSAntoine Leca 			ee.id = e1->id;
3745139afeeSAntoine Leca 			ee.type = e1->type;
3755139afeeSAntoine Leca 		} else {
3765139afeeSAntoine Leca 			e1 = &ee;
3775139afeeSAntoine Leca 			e2 = &ents2[i2++];
3785139afeeSAntoine Leca 			ee.id = e2->id;
3795139afeeSAntoine Leca 			ee.type = e2->type;
3805139afeeSAntoine Leca 		}
3815139afeeSAntoine Leca 		switch (e1->type) {
3825139afeeSAntoine Leca 		case 'f':
3835139afeeSAntoine Leca 			if (cflag != 0) {
3845139afeeSAntoine Leca 				if (e1->flag == e2->flag)
3855139afeeSAntoine Leca 					printf("\t%s\n", ents1[i1].id);
3865139afeeSAntoine Leca 				continue;
3875139afeeSAntoine Leca 			}
3885139afeeSAntoine Leca 			if (e1->flag == e2->flag)
3895139afeeSAntoine Leca 				continue;
3905139afeeSAntoine Leca 			break;
3915139afeeSAntoine Leca 		case 'n':
3925139afeeSAntoine Leca 			if (cflag != 0) {
3935139afeeSAntoine Leca 				if (e1->num == e2->num)
3945139afeeSAntoine Leca 					printf("\t%s#%d\n",
3955139afeeSAntoine Leca 					    ents1[i1].id, ents1[i1].num);
3965139afeeSAntoine Leca 				continue;
3975139afeeSAntoine Leca 			}
3985139afeeSAntoine Leca 			if (e1->num == e2->num)
3995139afeeSAntoine Leca 				continue;
4005139afeeSAntoine Leca 			break;
4015139afeeSAntoine Leca 		case 's':
4025139afeeSAntoine Leca 			if (cflag != 0) {
4035139afeeSAntoine Leca 				if (VALID_STRING(e1->str) &&
4045139afeeSAntoine Leca 				    VALID_STRING(e2->str) &&
4055139afeeSAntoine Leca 				    strcmp(e1->str, e2->str) == 0) {
4065139afeeSAntoine Leca 					printf("\t%s=", ents1[i1].id);
4075139afeeSAntoine Leca 					outstr(stdout, ents1[i1].str);
4085139afeeSAntoine Leca 					printf("\n");
4095139afeeSAntoine Leca 				}
4105139afeeSAntoine Leca 				continue;
4115139afeeSAntoine Leca 			}
4125139afeeSAntoine Leca 			if (VALID_STRING(e1->str) &&
4135139afeeSAntoine Leca 			    VALID_STRING(e2->str) &&
4145139afeeSAntoine Leca 			    strcmp(e1->str, e2->str) == 0)
4155139afeeSAntoine Leca 				continue;
4165139afeeSAntoine Leca 			break;
4175139afeeSAntoine Leca 		}
4185139afeeSAntoine Leca 		printf("\t%s: ", e1->id);
4195139afeeSAntoine Leca 		cprint_ent(e1);
4205139afeeSAntoine Leca 		if (e1->type == 'f')
4215139afeeSAntoine Leca 			printf(":");
4225139afeeSAntoine Leca 		else
4235139afeeSAntoine Leca 			printf(", ");
4245139afeeSAntoine Leca 		cprint_ent(e2);
4255139afeeSAntoine Leca 		printf(".\n");
4265139afeeSAntoine Leca 	}
4275139afeeSAntoine Leca }
4285139afeeSAntoine Leca 
4295139afeeSAntoine Leca static TERMINAL *
load_term(const char * name)4305139afeeSAntoine Leca load_term(const char *name)
4315139afeeSAntoine Leca {
4325139afeeSAntoine Leca 	TERMINAL *t;
4335139afeeSAntoine Leca 
4345139afeeSAntoine Leca 	t = calloc(1, sizeof(*t));
4355139afeeSAntoine Leca 	if (t == NULL)
4365139afeeSAntoine Leca 		err(1, "calloc");
4375139afeeSAntoine Leca 	if (name == NULL)
4385139afeeSAntoine Leca 		name = getenv("TERM");
4395139afeeSAntoine Leca 	if (name == NULL)
4405139afeeSAntoine Leca 		name = "dumb";
4415139afeeSAntoine Leca 	if (_ti_getterm(t, name, 1) == 1)
4425139afeeSAntoine Leca 		return t;
4435139afeeSAntoine Leca 
4445139afeeSAntoine Leca 	if (_ti_database == NULL)
4455139afeeSAntoine Leca 		errx(1, "no terminal definition found in internal database");
4465139afeeSAntoine Leca 	else
4475139afeeSAntoine Leca 		errx(1, "no terminal definition found in %s.db", _ti_database);
4485139afeeSAntoine Leca }
4495139afeeSAntoine Leca 
4505139afeeSAntoine Leca static void
show_missing(TERMINAL * t1,TERMINAL * t2,char type)4515139afeeSAntoine Leca show_missing(TERMINAL *t1, TERMINAL *t2, char type)
4525139afeeSAntoine Leca {
4535139afeeSAntoine Leca 	ssize_t i, max;
4545139afeeSAntoine Leca 	const char *id;
4555139afeeSAntoine Leca 
4565139afeeSAntoine Leca 	switch (type) {
4575139afeeSAntoine Leca 	case 'f':
4585139afeeSAntoine Leca 		max = TIFLAGMAX;
4595139afeeSAntoine Leca 		break;
4605139afeeSAntoine Leca 	case 'n':
4615139afeeSAntoine Leca 		max = TINUMMAX;
4625139afeeSAntoine Leca 		break;
4635139afeeSAntoine Leca 	default:
4645139afeeSAntoine Leca 		max = TISTRMAX;
4655139afeeSAntoine Leca 	}
4665139afeeSAntoine Leca 
4675139afeeSAntoine Leca 	for (i = 0; i <= max; i++) {
4685139afeeSAntoine Leca 		switch (type) {
4695139afeeSAntoine Leca 		case 'f':
4705139afeeSAntoine Leca 			if (t1->flags[i] != ABSENT_BOOLEAN ||
4715139afeeSAntoine Leca 			    t2->flags[i] != ABSENT_BOOLEAN)
4725139afeeSAntoine Leca 				continue;
4735139afeeSAntoine Leca 			id = _ti_flagid(i);
4745139afeeSAntoine Leca 			break;
4755139afeeSAntoine Leca 		case 'n':
4765139afeeSAntoine Leca 			if (t1->nums[i] != ABSENT_NUMERIC ||
4775139afeeSAntoine Leca 			    t2->nums[i] != ABSENT_NUMERIC)
4785139afeeSAntoine Leca 				continue;
4795139afeeSAntoine Leca 			id = _ti_numid(i);
4805139afeeSAntoine Leca 			break;
4815139afeeSAntoine Leca 		default:
4825139afeeSAntoine Leca 			if (t1->strs[i] != ABSENT_STRING ||
4835139afeeSAntoine Leca 			    t2->strs[i] != ABSENT_STRING)
4845139afeeSAntoine Leca 				continue;
4855139afeeSAntoine Leca 			id = _ti_strid(i);
4865139afeeSAntoine Leca 			break;
4875139afeeSAntoine Leca 		}
4885139afeeSAntoine Leca 		printf("\t!%s.\n", id);
4895139afeeSAntoine Leca 	}
4905139afeeSAntoine Leca }
4915139afeeSAntoine Leca 
4925139afeeSAntoine Leca static TERMUSERDEF *
find_userdef(TERMINAL * term,const char * id)4935139afeeSAntoine Leca find_userdef(TERMINAL *term, const char *id)
4945139afeeSAntoine Leca {
4955139afeeSAntoine Leca 	size_t i;
4965139afeeSAntoine Leca 
4975139afeeSAntoine Leca 	for (i = 0; i < term->_nuserdefs; i++)
4985139afeeSAntoine Leca 		if (strcmp(term->_userdefs[i].id, id) == 0)
4995139afeeSAntoine Leca 			return &term->_userdefs[i];
5005139afeeSAntoine Leca 	return NULL;
5015139afeeSAntoine Leca }
5025139afeeSAntoine Leca 
5035139afeeSAntoine Leca static void
use_terms(TERMINAL * term,size_t nuse,char ** uterms)5045139afeeSAntoine Leca use_terms(TERMINAL *term, size_t nuse, char **uterms)
5055139afeeSAntoine Leca {
5065139afeeSAntoine Leca 	TERMINAL **terms;
5075139afeeSAntoine Leca 	TERMUSERDEF *ud, *tud;
5085139afeeSAntoine Leca 	size_t i, j, agree, absent, data;
5095139afeeSAntoine Leca 
5105139afeeSAntoine Leca 	terms = malloc(sizeof(**terms) * nuse);
5115139afeeSAntoine Leca 	if (terms == NULL)
5125139afeeSAntoine Leca 		err(1, "malloc");
5135139afeeSAntoine Leca 	for (i = 0; i < nuse; i++) {
5145139afeeSAntoine Leca 		if (strcmp(term->name, *uterms) == 0)
5155139afeeSAntoine Leca 			errx(1, "cannot use same terminal");
5165139afeeSAntoine Leca 		for (j = 0; j < i; j++)
5175139afeeSAntoine Leca 			if (strcmp(terms[j]->name, *uterms) == 0)
5185139afeeSAntoine Leca 				errx(1, "cannot use same terminal");
5195139afeeSAntoine Leca 		terms[i] = load_term(*uterms++);
5205139afeeSAntoine Leca 	}
5215139afeeSAntoine Leca 
5225139afeeSAntoine Leca 	for (i = 0; i < TIFLAGMAX + 1; i++) {
5235139afeeSAntoine Leca 		agree = absent = data = 0;
5245139afeeSAntoine Leca 		for (j = 0; j < nuse; j++) {
5255139afeeSAntoine Leca 			if (terms[j]->flags[i] == ABSENT_BOOLEAN ||
5265139afeeSAntoine Leca 			    terms[j]->flags[i] == CANCELLED_BOOLEAN)
5275139afeeSAntoine Leca 				absent++;
5285139afeeSAntoine Leca 			else {
5295139afeeSAntoine Leca 				data++;
5305139afeeSAntoine Leca 				if (term->flags[i] == terms[j]->flags[i])
5315139afeeSAntoine Leca 					agree++;
5325139afeeSAntoine Leca 			}
5335139afeeSAntoine Leca 		}
5345139afeeSAntoine Leca 		if (data == 0)
5355139afeeSAntoine Leca 			continue;
5365139afeeSAntoine Leca 		if (agree > 0 && agree + absent == nuse)
5375139afeeSAntoine Leca 			term->flags[i] = ABSENT_BOOLEAN;
5385139afeeSAntoine Leca 		else if (term->flags[i] == ABSENT_BOOLEAN)
5395139afeeSAntoine Leca 			term->flags[i] = CANCELLED_BOOLEAN;
5405139afeeSAntoine Leca 	}
5415139afeeSAntoine Leca 
5425139afeeSAntoine Leca 	for (i = 0; i < TINUMMAX + 1; i++) {
5435139afeeSAntoine Leca 		agree = absent = data = 0;
5445139afeeSAntoine Leca 		for (j = 0; j < nuse; j++) {
5455139afeeSAntoine Leca 			if (terms[j]->nums[i] == ABSENT_NUMERIC ||
5465139afeeSAntoine Leca 			    terms[j]->nums[i] == CANCELLED_NUMERIC)
5475139afeeSAntoine Leca 				absent++;
5485139afeeSAntoine Leca 			else {
5495139afeeSAntoine Leca 				data++;
5505139afeeSAntoine Leca 				if (term->nums[i] == terms[j]->nums[i])
5515139afeeSAntoine Leca 					agree++;
5525139afeeSAntoine Leca 			}
5535139afeeSAntoine Leca 		}
5545139afeeSAntoine Leca 		if (data == 0)
5555139afeeSAntoine Leca 			continue;
5565139afeeSAntoine Leca 		if (agree > 0 && agree + absent == nuse)
5575139afeeSAntoine Leca 			term->nums[i] = ABSENT_NUMERIC;
5585139afeeSAntoine Leca 		else if (term->nums[i] == ABSENT_NUMERIC)
5595139afeeSAntoine Leca 			term->nums[i] = CANCELLED_NUMERIC;
5605139afeeSAntoine Leca 	}
5615139afeeSAntoine Leca 
5625139afeeSAntoine Leca 	for (i = 0; i < TISTRMAX + 1; i++) {
5635139afeeSAntoine Leca 		agree = absent = data = 0;
5645139afeeSAntoine Leca 		for (j = 0; j < nuse; j++) {
5655139afeeSAntoine Leca 			if (terms[j]->strs[i] == ABSENT_STRING ||
5665139afeeSAntoine Leca 			    terms[j]->strs[i] == CANCELLED_STRING)
5675139afeeSAntoine Leca 				absent++;
5685139afeeSAntoine Leca 			else {
5695139afeeSAntoine Leca 				data++;
5705139afeeSAntoine Leca 				if (VALID_STRING(term->strs[i]) &&
5715139afeeSAntoine Leca 				    strcmp(term->strs[i],
5725139afeeSAntoine Leca 					terms[j]->strs[i]) == 0)
5735139afeeSAntoine Leca 					agree++;
5745139afeeSAntoine Leca 			}
5755139afeeSAntoine Leca 		}
5765139afeeSAntoine Leca 		if (data == 0)
5775139afeeSAntoine Leca 			continue;
5785139afeeSAntoine Leca 		if (agree > 0 && agree + absent == nuse)
5795139afeeSAntoine Leca 			term->strs[i] = ABSENT_STRING;
5805139afeeSAntoine Leca 		else if (term->strs[i] == ABSENT_STRING)
5815139afeeSAntoine Leca 			term->strs[i] = CANCELLED_STRING;
5825139afeeSAntoine Leca 	}
5835139afeeSAntoine Leca 
5845139afeeSAntoine Leca 	/* User defined caps are more tricky.
5855139afeeSAntoine Leca 	   First we set any to absent that agree. */
5865139afeeSAntoine Leca 	for (i = 0; i < term->_nuserdefs; i++) {
5875139afeeSAntoine Leca 		agree = absent = data = 0;
5885139afeeSAntoine Leca 		ud = &term->_userdefs[i];
5895139afeeSAntoine Leca 		for (j = 0; j < nuse; j++) {
5905139afeeSAntoine Leca 			tud = find_userdef(terms[j], ud->id);
5915139afeeSAntoine Leca 			if (tud == NULL)
5925139afeeSAntoine Leca 				absent++;
5935139afeeSAntoine Leca 			else {
5945139afeeSAntoine Leca 				data++;
5955139afeeSAntoine Leca 				switch (ud->type) {
5965139afeeSAntoine Leca 				case 'f':
5975139afeeSAntoine Leca 					if (tud->type == 'f' &&
5985139afeeSAntoine Leca 					    tud->flag == ud->flag)
5995139afeeSAntoine Leca 						agree++;
6005139afeeSAntoine Leca 					break;
6015139afeeSAntoine Leca 				case 'n':
6025139afeeSAntoine Leca 					if (tud->type == 'n' &&
6035139afeeSAntoine Leca 					    tud->num == ud->num)
6045139afeeSAntoine Leca 						agree++;
6055139afeeSAntoine Leca 					break;
6065139afeeSAntoine Leca 				case 's':
6075139afeeSAntoine Leca 					if (tud->type == 's' &&
6085139afeeSAntoine Leca 					    VALID_STRING(tud->str) &&
6095139afeeSAntoine Leca 					    VALID_STRING(ud->str) &&
6105139afeeSAntoine Leca 					    strcmp(ud->str, tud->str) == 0)
6115139afeeSAntoine Leca 						agree++;
6125139afeeSAntoine Leca 					break;
6135139afeeSAntoine Leca 				}
6145139afeeSAntoine Leca 			}
6155139afeeSAntoine Leca 		}
6165139afeeSAntoine Leca 		if (data == 0)
6175139afeeSAntoine Leca 			continue;
6185139afeeSAntoine Leca 		if (agree > 0 && agree + absent == nuse) {
6195139afeeSAntoine Leca 			ud->flag = ABSENT_BOOLEAN;
6205139afeeSAntoine Leca 			ud->num = ABSENT_NUMERIC;
6215139afeeSAntoine Leca 			ud->str = ABSENT_STRING;
6225139afeeSAntoine Leca 		}
6235139afeeSAntoine Leca 	}
6245139afeeSAntoine Leca 
6255139afeeSAntoine Leca 	/* Now add any that we don't have as cancelled */
6265139afeeSAntoine Leca 	for (i = 0; i < nuse; i++) {
6275139afeeSAntoine Leca 		for (j = 0; j < terms[i]->_nuserdefs; j++) {
6285139afeeSAntoine Leca 			ud = find_userdef(term, terms[i]->_userdefs[j].id);
6295139afeeSAntoine Leca 			if (ud != NULL)
6305139afeeSAntoine Leca 				continue; /* We have handled this */
6315139afeeSAntoine Leca 			term->_userdefs = realloc(term->_userdefs,
6325139afeeSAntoine Leca 			    sizeof(*term->_userdefs) * (term->_nuserdefs + 1));
6335139afeeSAntoine Leca 			if (term->_userdefs == NULL)
6345139afeeSAntoine Leca 				err(1, "malloc");
6355139afeeSAntoine Leca 			tud = &term->_userdefs[term->_nuserdefs++];
6365139afeeSAntoine Leca 			tud->id = terms[i]->_userdefs[j].id;
6375139afeeSAntoine Leca 			tud->type = terms[i]->_userdefs[j].flag;
6385139afeeSAntoine Leca 			tud->flag = CANCELLED_BOOLEAN;
6395139afeeSAntoine Leca 			tud->num = CANCELLED_NUMERIC;
6405139afeeSAntoine Leca 			tud->str = CANCELLED_STRING;
6415139afeeSAntoine Leca 		}
6425139afeeSAntoine Leca 	}
6435139afeeSAntoine Leca }
6445139afeeSAntoine Leca 
6455139afeeSAntoine Leca int
main(int argc,char ** argv)6465139afeeSAntoine Leca main(int argc, char **argv)
6475139afeeSAntoine Leca {
6485139afeeSAntoine Leca 	char *term, *Barg;
6495139afeeSAntoine Leca 	int ch, uflag;
6505139afeeSAntoine Leca 	TERMINAL *t, *t2;
6515139afeeSAntoine Leca 	size_t n, n2;
6525139afeeSAntoine Leca 	struct winsize ws;
6535139afeeSAntoine Leca 	TIENT ents[TISTRMAX + 1], ents2[TISTRMAX + 1];
6545139afeeSAntoine Leca 
6555139afeeSAntoine Leca 	cols = 80; /* default */
6565139afeeSAntoine Leca 	term = getenv("COLUMNS");
6575139afeeSAntoine Leca 	if (term != NULL)
6585139afeeSAntoine Leca 		cols = strtoul(term, NULL, 10);
6595139afeeSAntoine Leca 	else if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0)
6605139afeeSAntoine Leca 		cols = ws.ws_col;
6615139afeeSAntoine Leca 
6625139afeeSAntoine Leca 	uflag = xflag = 0;
6635139afeeSAntoine Leca 	Barg = NULL;
6645139afeeSAntoine Leca 	while ((ch = getopt(argc, argv, "1A:B:acnquw:x")) != -1)
6655139afeeSAntoine Leca 		switch (ch) {
6665139afeeSAntoine Leca 		case '1':
6675139afeeSAntoine Leca 			cols = 1;
6685139afeeSAntoine Leca 			break;
6695139afeeSAntoine Leca 		case 'A':
6705139afeeSAntoine Leca 			setdb(optarg);
6715139afeeSAntoine Leca 			break;
6725139afeeSAntoine Leca 		case 'B':
6735139afeeSAntoine Leca 			Barg = optarg;
6745139afeeSAntoine Leca 			break;
6755139afeeSAntoine Leca 		case 'a':
6765139afeeSAntoine Leca 			aflag = 1;
6775139afeeSAntoine Leca 			break;
6785139afeeSAntoine Leca 		case 'c':
6795139afeeSAntoine Leca 			cflag = 1;
6805139afeeSAntoine Leca 			break;
6815139afeeSAntoine Leca 		case 'n':
6825139afeeSAntoine Leca 			nflag = 1;
6835139afeeSAntoine Leca 			break;
6845139afeeSAntoine Leca 		case 'q':
6855139afeeSAntoine Leca 			qflag = 1;
6865139afeeSAntoine Leca 			break;
6875139afeeSAntoine Leca 		case 'u':
6885139afeeSAntoine Leca 			uflag = 1;
6895139afeeSAntoine Leca 			aflag = 1;
6905139afeeSAntoine Leca 			break;
6915139afeeSAntoine Leca 		case 'w':
6925139afeeSAntoine Leca 			cols = strtoul(optarg, NULL, 10);
6935139afeeSAntoine Leca 			break;
6945139afeeSAntoine Leca 		case 'x':
6955139afeeSAntoine Leca 			xflag = 1;
6965139afeeSAntoine Leca 			break;
6975139afeeSAntoine Leca 		case '?':
6985139afeeSAntoine Leca 		default:
6995139afeeSAntoine Leca 			fprintf(stderr,
7005139afeeSAntoine Leca 			    "usage: %s [-1acnqux] [-A database] [-B database] "
7015139afeeSAntoine Leca 			    "[-w cols] [term]\n",
7025139afeeSAntoine Leca 			    getprogname());
7035139afeeSAntoine Leca 			return EXIT_FAILURE;
7045139afeeSAntoine Leca 		}
7055139afeeSAntoine Leca 	cols--;
7065139afeeSAntoine Leca 
7075139afeeSAntoine Leca 	if (optind + 1 < argc)
7085139afeeSAntoine Leca 		aflag = 1;
7095139afeeSAntoine Leca 
7105139afeeSAntoine Leca 	if (optind < argc)
7115139afeeSAntoine Leca 		term = argv[optind++];
7125139afeeSAntoine Leca 	else
7135139afeeSAntoine Leca 		term = NULL;
7145139afeeSAntoine Leca 	t = load_term(term);
7155139afeeSAntoine Leca 
7165139afeeSAntoine Leca 	if (uflag != 0)
7175139afeeSAntoine Leca 		use_terms(t, argc - optind, argv + optind);
7185139afeeSAntoine Leca 
7195139afeeSAntoine Leca 	if ((optind + 1 != argc && nflag == 0) || uflag != 0) {
7205139afeeSAntoine Leca 		if (uflag == 0) {
7215139afeeSAntoine Leca 			printf("# Reconstructed from ");
7225139afeeSAntoine Leca 			if (_ti_database == NULL)
7235139afeeSAntoine Leca 				printf("internal database\n");
7245139afeeSAntoine Leca 			else
7255139afeeSAntoine Leca 				printf("%s%s\n", _ti_database,
726*84d9c625SLionel Sambuc 				    *_ti_database == '/' ? ".cdb" : "");
7275139afeeSAntoine Leca 		}
7285139afeeSAntoine Leca 		printf("%s", t->name);
7295139afeeSAntoine Leca 		if (t->_alias != NULL && *t->_alias != '\0')
7305139afeeSAntoine Leca 			printf("|%s", t->_alias);
7315139afeeSAntoine Leca 		if (t->desc != NULL && *t->desc != '\0')
7325139afeeSAntoine Leca 			printf("|%s", t->desc);
7335139afeeSAntoine Leca 		printf(",\n");
7345139afeeSAntoine Leca 
7355139afeeSAntoine Leca 		n = load_ents(ents, t, 'f');
7365139afeeSAntoine Leca 		print_ent(ents, n);
7375139afeeSAntoine Leca 		n = load_ents(ents, t, 'n');
7385139afeeSAntoine Leca 		print_ent(ents, n);
7395139afeeSAntoine Leca 		n = load_ents(ents, t, 's');
7405139afeeSAntoine Leca 		print_ent(ents, n);
7415139afeeSAntoine Leca 
7425139afeeSAntoine Leca 		if (uflag != 0) {
7435139afeeSAntoine Leca 			printf("\t");
7445139afeeSAntoine Leca 			n = SW;
7455139afeeSAntoine Leca 			for (; optind < argc; optind++) {
7465139afeeSAntoine Leca 				n2 = 5 + strlen(argv[optind]);
7475139afeeSAntoine Leca 				if (n != SW) {
7485139afeeSAntoine Leca 					if (n + n2 > cols) {
7495139afeeSAntoine Leca 						printf("\n\t");
7505139afeeSAntoine Leca 						n = SW;
7515139afeeSAntoine Leca 					} else
7525139afeeSAntoine Leca 						n += printf(" ");
7535139afeeSAntoine Leca 				}
7545139afeeSAntoine Leca 				n += printf("use=%s,", argv[optind]);
7555139afeeSAntoine Leca 			}
7565139afeeSAntoine Leca 			printf("\n");
7575139afeeSAntoine Leca 		}
7585139afeeSAntoine Leca 		return EXIT_SUCCESS;
7595139afeeSAntoine Leca 	}
7605139afeeSAntoine Leca 
7615139afeeSAntoine Leca 	if (Barg == NULL)
7625139afeeSAntoine Leca 		unsetenv("TERMINFO");
7635139afeeSAntoine Leca 	else
7645139afeeSAntoine Leca 		setdb(Barg);
7655139afeeSAntoine Leca 	t2 = load_term(argv[optind++]);
7665139afeeSAntoine Leca 	printf("comparing %s to %s.\n", t->name, t2->name);
7675139afeeSAntoine Leca 	if (qflag == 0)
7685139afeeSAntoine Leca 		printf("    comparing booleans.\n");
7695139afeeSAntoine Leca 	if (nflag == 0) {
7705139afeeSAntoine Leca 		n = load_ents(ents, t, 'f');
7715139afeeSAntoine Leca 		n2 = load_ents(ents2, t2, 'f');
7725139afeeSAntoine Leca 		compare_ents(ents, n, ents2, n2);
7735139afeeSAntoine Leca 	} else
7745139afeeSAntoine Leca 		show_missing(t, t2, 'f');
7755139afeeSAntoine Leca 	if (qflag == 0)
7765139afeeSAntoine Leca 		printf("    comparing numbers.\n");
7775139afeeSAntoine Leca 	if (nflag == 0) {
7785139afeeSAntoine Leca 		n = load_ents(ents, t, 'n');
7795139afeeSAntoine Leca 		n2 = load_ents(ents2, t2, 'n');
7805139afeeSAntoine Leca 		compare_ents(ents, n, ents2, n2);
7815139afeeSAntoine Leca 	} else
7825139afeeSAntoine Leca 		show_missing(t, t2, 'n');
7835139afeeSAntoine Leca 	if (qflag == 0)
7845139afeeSAntoine Leca 		printf("    comparing strings.\n");
7855139afeeSAntoine Leca 	if (nflag == 0) {
7865139afeeSAntoine Leca 		n = load_ents(ents, t, 's');
7875139afeeSAntoine Leca 		n2 = load_ents(ents2, t2, 's');
7885139afeeSAntoine Leca 		compare_ents(ents, n, ents2, n2);
7895139afeeSAntoine Leca 	} else
7905139afeeSAntoine Leca 		show_missing(t, t2, 's');
7915139afeeSAntoine Leca 	return EXIT_SUCCESS;
7925139afeeSAntoine Leca }
793